指针
声明变量并对变量赋值,Go Runtime会根据变量的数据类型在RAM中分配指定大小的内存用来存储变量
上述的内存地址就是十六进制的数字
如何定义指针
- 使用 &变量名 获取变量的内存地址
- 使用 *变量名 获取指针变量的值
_
package mainimport "fmt"func main() {a := 1var pa *intpa = &afmt.Printf("pointer pa of type %T value %v\n pointer value %v", pa, pa, *pa)}
指针与变量的区别
_
- 变量存储的是内存地址存储的值
- 指针存储的是内存的地址
The new function
Go内置可以申请内存并且返回指向该内存的指针的函数new
package mainimport "fmt"func main() {pa := new(int)fmt.Printf("data at %T is %v\n", pa, *pa) // data at *int is 0}
不知你是否会有疑问,pa的指针的值为什么是0而不是nil?
- 指针的值是nil意味着指针并没有指向任何内存地址
- 一旦对指针赋值内存地址,对应的内存地址就必须要存储值
- 使用 func new(Type) *Type 创建的指针并对指针赋值,结合上例默认值为0
将指针作为函数参数
参数是变量指针
package mainimport "fmt"func changeValue(p *int) {*p = 2}func main() {a := 1pa := &achangeValue(pa)fmt.Printf("Value is %v", a)}
上述代码可以简化为:
package mainimport "fmt"func changeValue(p *int) {*p = 2}func main() {a := 1changeValue(&a)fmt.Printf("Value is %v", a)}
参数是数组指针
**
package mainimport "fmt"func changeValue(p *[3]int) {p[0] *= 2p[1] *= 2p[2] *= 2}func main() {a := [3]int{ 1,2,3 }changeValue(&a)fmt.Printf("value is %v", a)}
- golang 语言中只有 3 种引用类型,分别为切片 slice、字段 map、管道 channel
- 引用类型可以简单理解为指针类型,可以通过 make 完成初始化
- 对于结构体指针,golang可以通过指针或直接访问内部属性
slice := make([]int, 0, 100)hash := make(map[int]bool, 10)ch := make(chan int, 5)
指针类型的数组 VS 数组类型的指针
package mainimport "fmt"func changeValue(arr [3]*int) [3]*int {d := 50arr[1] = &dreturn arr}func main() {a := 10b := 20c := 30arr := [...]*int {&a, &b, &c}fmt.Printf("The value is %v\n", arr)ret := changeValue(arr)fmt.Printf("The value is %v", ret)}
