如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。更多往期文章在我的个人博客
指针的含义是存储变量、常量所在的内存地址
。
区别于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
*/ }
总结: 取地址操作符&和取值操作符是一对互补操作符,&取出地址,根据地址取出地址指向的值。
变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
- 对变量进行取地址(&)操作,可以获得这个变量的指针变量。
- 指针变量的值是指针地址。
- 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。 指针传值示例:
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(“空值”) } }