• Go语言入门【7】指针


    指针

    在go语言中,每一个变量在运行时都会拥有一个地址,这个地址代表的就是变量在内存中的位置,而指针就是指向这个地址的变量。使用go语言中的指针很简单,只需要记住两个关键字符,&(取地址符)和*(取值符)。

    取地址符

    取地址符的使用很简单,只需要在变量前面加上取地址符&即可取到该变量在内存中的地址,保存地址的变量就称为指针。

    package main
    
    import "fmt"
    
    func main() {
      a := 1      // 定义一个变量a,并赋值为1
      b := &a      // 通过取地址符取出变量a在内存中的地址
      fmt.Println(b)  // 打印取出的地址
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行结果:每个人的运行结果不一样,只要打印的是如下格式的内容表示成功。

    取值符

    通过上面的取地址符能够取出变量a在内存中的地址,然后通过地址同样可以取出变量对应的值,取值符* 使用在第一步取出的地址变量之前即可取出对应的值。

    package main
    
    import "fmt"
    
    func main() {
      a := 1
      b := &a
      c := *b
      fmt.Printf("b的类型:%T \n", b)
      fmt.Printf("c的值:%d \n", c)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    此时的指针b中保存的就是变量a在内存中的地址,**变量b此时的类型为*int,称作int的指针类型,**通过取值符*b则可以取到b地址对应的变量值。

    运行结果:

    指针声明

    go语言中的值类型int float32 string等都有其对应的指针类型:*int *float32 *string,在声明指针时,需要使用到指针类型。

    语法:

    var 指针名 *类型
    
    • 1

    代码示例:

    package main
    
    import "fmt"
    
    func main() {
      var a *int      // 定义一个指针类型
      fmt.Println(a)    // 输出为
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    上面定义了一个指针a,但是指针a没有分配到变量时,其值就为nil,称之为空指针

    直接给指针赋值

    package main
    
    import "fmt"
    
    func main() {
      var a *int
      *a = 1
      fmt.Println(a)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果如上所示直接运行,代码会产生报错,报错信息如下,报错原因是在Go语言中对于引用类型的变量,在使用的时候不仅要声明,还要为其分配内存空间,否则赋的值就没办法存储。而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。

    new

    函数签名:

    func new(Type) *Type
    
    • 1

    使用new函数时,传入一个类型,返回一个指向该类型内存地址的指针,使用new得到的指针其对应的值为该类型的默认值。

    a := new(int)
    b := new(bool)
    fmt.Println(*a)       // 默认值为 0
    fmt.Println(*b)       // 默认值为 false
    
    • 1
    • 2
    • 3
    • 4

    上面的var a *int只是声明了一个指针并没有初始化分配内存空间,所以才会报错,如果使用new进行初始化指针就没有问题了。

    package main
    
    import "fmt"
    
    func main() {
      a := new(int)
      *a = 1
      fmt.Printf("a的值:%d \n", *a)
      fmt.Printf("a的类型:%T \n", a)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果:

  • 相关阅读:
    Swift新async/await并发模型中子任务取消不能被其它子任务感知的原因及解决
    基于web的学校二手书城系统/二手书交易系统
    Java11-Object类,常用API
    RoadBEV:鸟瞰图中的道路表面重建
    全球DTC品牌纷纷奔走线下,价值岂止于用户体验和品牌形象
    前端面试题:html和css面试题
    LeetCode 1282. Group the People Given the Group Size They Belong To【哈希表】1267
    js实现在可视区内,文字图片动画效果
    Python进阶——多进程多线程
    位于同一子网下的ip在子网掩码配置错误的情况下如何进行通信(wireshrak抓包分析)
  • 原文地址:https://blog.csdn.net/qq_41286145/article/details/128038162