Go 语言的指针 Go 语言中获取内存地址 Go语言使用&
符号来取地址
1 2 3 4 5 6 7 8 9 10 package mainimport "fmt" func main () { var lv int = 10 fmt.Println(&lv) }
执行结果为:
Go语言中的指针 一个指针变量指向了一个值的内存地址, 指针也是一种数据类型, 在使用之前, 你需要先声明指针
1 2 var age *int var name *string
*变量: * 变量是一种占位符, 用于引用计算机内存的地址, 可以理解为内存地址的标签
*指针: * 指向其他变量内存地址的值
*&: * 取变量的内存地址
*\ : ** 取指针指向的内存地址的值
比喻: 现屋里有一个2*2的箱子, 左下角箱子的编号是1-1
标签贴了苹果, 右下角箱子的编号是1-2
标签贴了玉米, 左上角箱子的编号是2-1
标签贴了桃子, 右上角箱子的编号是2-2
标签贴了土豆, 房间里还立着一个大指示牌. 🔜 如下图所示
1 2 3 4 5 6 7 8 9 10 ----------------- |桃子🍑 | 土豆🥔 | |2-1 | 2-2 | ----------------| |苹果🍎 | 玉米🌽 | |1-1 |1-2 | ----------------- 🔜 指示牌
变量: 变量就是箱子上的标签, 桃子就是一个变量名, 而箱子里的桃子🍑则是值
值: 实际保存内容的地方, 也就是实际放在盒子里的东西
指针: 指针就理解为摆在房间里的指示牌, 指示牌可以指向任意一个箱子的地址, 也就是可以指向1-1
1-2
2-1
或 2-2
&: 获取变量的地址, 用在变量名前面, 理解为获取标签的地址, 比如&玉米, 意思就是获取玉米所在箱子的地址, 也就是1-2
*: 获取指针指向内存地址的值, 假如该指针指向了玉米的地址, 则使用*
获取该指针的值即为箱子里所有的玉米🌽
*注意: * 指针是有数据类型的, 比如你声明了一个水果类型的指针, 那么这个指针(这个指示牌)就只能指向1-1
或 2-1
这两个地址, 因为只有这两个地址的值类型为水果; 同理, 如果你声明了一个蔬菜类型的指针, 也只能指向 1-2
和 2-2
这两块内存地址, 下面介绍指针的使用时, 仍将使用到该比喻
指针的使用
定义指针变量
为指针赋值
访问指针变量中指向地址的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mainimport "fmt" func main () { var fruit int = 59 var indicator *int indicator = &fruit fmt.Println(*indicator) }
执行结果为:
空指针 当一个指针被声明后, 却没有被赋予任何变量的内存地址, 此时, 该指针的值为nil
, nil指针也被称作空指针
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值, 一个指针变量通常缩写为 ptr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mainimport "fmt" func main () { var ptr *int fmt.Println(ptr) if ptr == nil { fmt.Println("ptr为空指针" ) } else { fmt.Println("ptr为非空指针" ) } }
执行结果为:
Go指针引用之向函数传递指针参数 值传递? 引用传递?
在Python中, 除了像int, str这样基本数据类型是值传递外, 其余绝大部分都是引用传递. 而在Go语言中, 只有值传递一种方式, Go语言中是通过传递指针来实现引用传递的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 package mainimport "fmt" func swap1 (a, b int ) { b, a = a, b } func swap2 (a, b *int ) { c := *a *a = *b *b = c } func swap3 (a, b *int ) { *a, *b = *b, *a } func swap4 (a, b int ) (int , int ) { return b, a } func main () { a, b := 5 , 9 swap1(a, b) fmt.Println(a, b) swap2(&a, &b) fmt.Println(a, b) swap3(&a, &b) fmt.Println(a, b) a, b = swap4(a, b) fmt.Println(a, b) }
以上交换的场景中, swap4为最佳方案, 简单有效! 指针在实际使用中也要充分考虑使用场景, 是否非用指针不可
Go指针引用之指向指针的指针 待续…