Golang 指针

Golang 指针

Posted by 锐玩道 on May 21, 2021

如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。更多往期文章在我的个人博客

指针的含义是存储变量、常量所在的内存地址

区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针。

要搞明白Go语言中的指针需要先知道3个概念:指针地址、指针类型、指针取值。

使用指针的好处:

  • Golang 的指针操作十分简单,只需要记住:&(取地址)*(根据地址取值)
  • Go语言中的函数传参都是值拷贝。所以需要修改某个变量,我们可以创建一个指向该变量地址指针。传递数据使用指针,而无须拷贝数据。

指针地址和指针类型

程序运行时,每个变量都拥有一个地址,代表变量在内存中的位置。

Golang 中使用 & 放在变量前面对变量进行 取地址 操作。 Golang 中的值类型都有对应的指针类型,如:int => (int、int64),string => (*string)。

取变量指针的语法如下,&(取地址)*(根据地址取值) 举个例子:

func main() { a := 10 // 变量 a, 值类型为 int,值为 10,内存地址 0xc00001a078 b := &a // 变量 b, 值类型为 int,值为 0xc00001a078(a的内存地址),内存地址 0xc00000e018 (:= 为定义变量并初始化值,会向内存申请新地址 0xc00000e018)

fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10,因为`&(取地址)` 所以&a代表a的内存地址:0xc00001a078
fmt.Printf("b:%p type:%T\n", b, &b) // b:0xc00001a078 因为`&(取地址)` 所以&a代表a的内存地址:0xc00000e018 }

指针取值

  • 在对普通变量使用& 取地址后会获得变量的指针
  • 对指针使用* 根据地址后会获得地址存放的值,指针取值代码如下。

func main() { a := 10 b := &a // 取变量a的地址,将指针保存到b中 fmt.Printf(“type of b:%T\n”, b)

c := *b // 指针取值(根据指针去内存取值)
fmt.Printf("type of c:%T\n", c)
fmt.Printf("value of c:%v\n", c)

/*
输出如下:
    type of b:*int
    type of c:int
    value of c:10
*/ }

总结: 取地址操作符&和取值操作符是一对互补操作符,&取出地址,根据地址取出地址指向的值。

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

  1. 对变量进行取地址(&)操作,可以获得这个变量的指针变量。
  2. 指针变量的值是指针地址。
  3. 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。 指针传值示例:

func modify1(x int) { x = 100 }

func modify2(x *int) { *x = 100 }

func main() { a := 10 modify1(a) fmt.Println(a) // 10 modify2(&a) fmt.Println(a) // 100 }

空指针

当一个指针被定义后没有分配到任何变量时,它的值为 nil 空指针的判断 package main

import “fmt”

func main() { var p *string fmt.Println(p) fmt.Printf(“p的值是%v\n”, p) if p != nil { fmt.Println(“非空”) } else { fmt.Println(“空值”) } }