• Golang


    Golang - 复合类型

     

    Golang - 复合类型

    1. 指针

    • go语言中指针是很容易学习的,比C中容易的多,它可以更简单地执行一些任务
    • 与变量类似,使用前需要声明,使用&符号可以取内存地址
    • 声明指针的格式:
      • var 指针变量名 *指针类型

    指针的使用

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func main() {
        //声明变量
        var a int = 20
    
        //声明指针变量
        var p *int
        p = &a
    
        //十六进制
        fmt.Printf("a变量的地址是: %x
    ", &a)
        fmt.Printf("p变量存储的指针地址: %x
    ", p)
    
        //使用指针访问值
        fmt.Printf("*p变量的值: %d
    ", *p)
    }
    
    
    //a变量的地址是: c042052080
    //p变量存储的指针地址: c042052080
    //*p变量的值: 20

    通过指针修改变量

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func main() {
        //定义变量
        var num int = 10
        fmt.Println(&num)
        var ptr *int
    
        //指针赋值
        ptr = &num
        //通过指针修改num
        * ptr = 20
        fmt.Println(num)
    }
    
    //0xc042052080
    //20

    go空指针

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func main() {
        var ptr *int
        fmt.Println("ptr的值为:", ptr)
    
        //判断空指针
        if ptr == nil{
            fmt.Println("是空")
        }
    }
    
    //ptr的值为: <nil>
    //是空

    值传递和引用传递

    void pass_by_val(int a){
    a++;
    }
    
    void pass_by_ref(int& a){
    a++;
    }
    
    int main() {
    int a = 3;
    
    pass_by_val(a);
    printf("pass_by_val: %d
    ", a)
    printf("pass_by_ref: %d
    ", a)
    }
    
    答案:3,4

    值传递:

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func swap(a, b int){
        a, b = b, a
    }
    
    func main() {
        a, b := 3, 4
        swap(a, b)
        fmt.Println(a, b)
    }
    
    // 3  4

    go引用传递:

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func swap(a, b *int){
        *a, *b = *b, *a
    }
    
    func main() {
        a, b := 3, 4
        swap(&a, &b)
        fmt.Println(a, b)
    }
    
    // 4  3

    2. new()和make()

    • new()用来分配内存,但与其他语言中的同名函数不同,它不会初始化内存,只会将内存置零
    • make(T)会返回一个指针,该指针指向新分配的,类型为T的零值,适用于创建结构体
    • make()的目的不同于new(),它只能创建slice、map、channel,并返回类型为T(非指针)的已初始化(非零值)的值

      //package 声明开头表示代码所属包
      package main
      
      import "fmt"
      
      func main() {
          p :=new([]int)
          fmt.Println(p)
      
          //[]int切片
          //10: 初始化10个长度
          //50: 容量为50
          m :=make([]int, 10, 50)
          fmt.Println(m)
      
          m[0] = 10
          (*p)[0] = 10
          fmt.Println(p)
      }

    3. 数组

    声明变量:

    var 数组名[数组长度] 数组类型

    声明和初始化数组:

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    
    func main() {
        //数组长度不让变化
        //定义int类型数组
        var arr1 [5]int
    
        //:=声明并赋值
        arr2 := [3]int{1, 2, 3}
    
        //可以省略大小
        arr3 := [10]int{2, 4, 6, 8, 10}
        fmt.Println(arr1, arr2, arr3)
    
        //定义二维数组
        var grid [4][5]int
        fmt.Println(grid)
    }
    
    //[0 0 0 0 0] [1 2 3] [2 4 6 8 10 0 0 0 0 0]
    //[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

    数组是值类型还是引用类型?

    package main
    
    import "fmt"
    
    //传入数组,修改元素
    func printArr(arr [5]int)  {
       //修改一个元素
       arr[0] = 100
       for i,v := range arr{
          fmt.Println(i,v)
       }
    }
    
    func main() {
       //定义数组
       var arr1 [5]int
    
    //:=声明并赋值
       arr2 := [3]int{1, 2, 3}
       //可以省略大小
       arr3 := [...]int{2, 4, 6, 8, 10}
       fmt.Println(arr1, arr2, arr3)
    
       //printArr(arr1)
       //报错
       //printArr(arr2)
       printArr(arr3)
    
       //打印原始值
       fmt.Println()
       fmt.Println(arr3)
    }

    4. slice

    • 数组的长度在定义之后无法再次修改,go语言提供了数组切片(slice)来弥补数组的不足
    • 创建切片的各种方式

        //package 声明开头表示代码所属包
        package main
      
        import "fmt"
      
        func main() {
            //声明空切片
            var s1 []int
      
            //:=声明
            s2 :=[]int{}
      
            var s3 []int = make([]int, 0)
            s4 :=make([]int, 0, 0)
            fmt.Println(s1, s2, s3, s4)
        }
      
      
        [] [] [] []

    .

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func main() {
        //定义数组
        arr :=[...]int{0, 1, 2, 3, 4, 5, 6, 7}
    
        //切片取值
        fmt.Println(arr[2:6])
        fmt.Println(arr[:6])
        fmt.Println(arr[2:])
        fmt.Println(arr[:])
    }
    
    
    //[2 3 4 5]
    //[0 1 2 3 4 5]
    //[2 3 4 5 6 7]
    //[0 1 2 3 4 5 6 7]

    go切片可以向后扩展, 但不能向前扩展

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func main() {
        //定义数组
        arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
        s1 := arr[2:6]
        fmt.Println(s1)
        s2 := s1[3:5]
        fmt.Println(s2)
        
        //切片添加元素
        s3 := append(s2,10)
        fmt.Println(s3)
        fmt.Println(arr)
    
        s4 := append(s3,11)
        fmt.Println(s4)
        fmt.Println(arr)
        s5:= append(s4,12)
        fmt.Println(s5)
        fmt.Println(arr)
    }
    
    //[2 3 4 5]
    //[5 6]
    //[5 6 10]
    //[0 1 2 3 4 5 6 10]
    //[5 6 10 11]
    //[0 1 2 3 4 5 6 10]
    //[5 6 10 11 12]
    //[0 1 2 3 4 5 6 10]

    内建函数copy()

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func main() {
        //切片
        data := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
        s1 := data[8:]
        s2 := data[:5]
        fmt.Println(s1)
        fmt.Println(s2)
    
        //将第二个拷贝到第一个里
        copy(s2, s1)
        fmt.Println(s2)
        fmt.Println(data)
    }
    
    //[8 9]
    //[0 1 2 3 4]
    //[8 9 2 3 4]
    //[8 9 2 3 4 5 6 7 8 9]

    5. Map

    • Map 是go内置的数据结构,是一种无序的键值对的集合,可以通过key快速找到value的值
    • 定义Map:
      • var 变量名 map[key的数据类型] value的数据类型
      • 创建map

            //package 声明开头表示代码所属包
            package main
        
            import "fmt"
        
            func main() {
                //声明map
                var mmp map[int]string
                fmt.Println(mmp == nil)
        
                //m2和m3是等价的
                m2 := map[int]string{}
                m3 :=make(map[int]string)
                fmt.Println(m2, m3)
        
                m4 :=make(map[int]string, 10)
                fmt.Println(m4)
            }
        
            //true
            //map[] map[]
            //map[]

    初始化map

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    func main() {
        //1. 定义同时初始化
        var m1 map[int]string = map[int]string{1:"超哥", 2:"最帅"}
        fmt.Println(m1)
    
        //2. 自动推导类型 :=
        m2 :=map[int]string{1:"超哥", 2:"最帅"}
        fmt.Println(m2)
    }
    
    //map[1:超哥 2:最帅]
    //map[1:超哥 2:最帅]

    键值操作

    //package 声明开头表示代码所属包
    package main
    
    func main() {
        m1 :=map[int]string{1:"111",2:"222"}
        
        //修改
        m1[1]="1111"
        //追加
        m1[3]="333"
    }

    6. 结构体

    • go语言没有class,只是个结构体struct
    • 结构体定义:
      • type 结构体名 struct{}
    • 结构体初始化

    //package 声明开头表示代码所属包
    package main

    import "fmt"
    
    //定义学生结构体
    type Student struct {
        id int
        name string
        sex byte
        age int
        addr string
    }
    
    func main() {
        //1.顺序初始化
        var s1 Student = Student{1,"约汉",'f',18,"bj"}
        fmt.Println(s1)
        s2 := Student{2,"接客",'m',20,"sh"}
        fmt.Println(s2)
        //s3 := Student{3,"撸死",'m',25}
    
        //2.指定初始化成员
        s4 := Student{id:4,age:26}
        fmt.Println(s4)
        fmt.Println(s4.id)
    
        //3.结构体作为指针变量初始化
        var s5 *Student = &Student{5,"接客",'f',20,"sh"}
        fmt.Println(s5)
        //指针类型访问变量
        //go底层自己实现了转换,下面2种都可以取指针对象的属性
        fmt.Println((*s5).id)
        fmt.Println(s5.id)
    
        s6 := &Student{6,"接客",'m',20,"sh"}
        fmt.Println(s6)
    }
    
    //{1 约汉 102 18 bj}
    //{2 接客 109 20 sh}
    //{4  0 26 }
    //4
    //&{5 接客 102 20 sh}
    //5
    //5
    //&{6 接客 109 20 sh}

    7. 结构体参数

    结构体可以作为函数参数传递

    //package 声明开头表示代码所属包
    package main
    
    import "fmt"
    
    type Student struct {
        id   int
        name string
        sex  string
        age  int
        addr string
    }
    
    //定义传递学生对象的方法
    func tmpStudent(tmp Student) {
        //修改id
        tmp.id = 250
        fmt.Println("tmp=", tmp)
    }
    
    //定义传递指针类型的对象的方法
    func tmpStudent2(p *Student) {
        //修改id
        p.id = 249
        fmt.Println("tmp2=", p)
    }
    
    func main() {
        var s Student = Student{1, "接客", "female", 20, "sz"}
        tmpStudent(s)
        fmt.Println("main s =", s)
        //传递指针地址
        tmpStudent2(&s)
        fmt.Println("main s2=", s)
    }
    
    //tmp= {250 接客 female 20 sz}
    //main s = {1 接客 female 20 sz}
    //tmp2= &{249 接客 female 20 sz}
    //main s2= {249 接客 female 20 sz}
     
     
  • 相关阅读:
    将vue文件script代码抽取到单独的js文件
    git pull 提示错误:Your local changes to the following files would be overwritten by merge
    vue和uniapp 配置项目基础路径
    XAMPP Access forbidden! Access to the requested directory is only available from the local network.
    postman与newman集成
    postman生成代码段
    Curl命令
    POST方法的Content-type类型
    Selenium Grid 并行的Web测试
    pytorch转ONNX以及TnesorRT的坑
  • 原文地址:https://www.cnblogs.com/yanghongtao/p/10970378.html
Copyright © 2020-2023  润新知