指针
声明变量并对变量赋值,Go Runtime会根据变量的数据类型在RAM中分配指定大小的内存用来存储变量
上述的内存地址就是十六进制的数字
如何定义指针
- 使用 &变量名 获取变量的内存地址
- 使用 *变量名 获取指针变量的值
_
package main
import "fmt"
func main() {
a := 1
var pa *int
pa = &a
fmt.Printf("pointer pa of type %T value %v\n pointer value %v", pa, pa, *pa)
}
指针与变量的区别
_
- 变量存储的是内存地址存储的值
- 指针存储的是内存的地址
The new function
Go内置可以申请内存并且返回指向该内存的指针的函数new
package main
import "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 main
import "fmt"
func changeValue(p *int) {
*p = 2
}
func main() {
a := 1
pa := &a
changeValue(pa)
fmt.Printf("Value is %v", a)
}
上述代码可以简化为:
package main
import "fmt"
func changeValue(p *int) {
*p = 2
}
func main() {
a := 1
changeValue(&a)
fmt.Printf("Value is %v", a)
}
参数是数组指针
**
package main
import "fmt"
func changeValue(p *[3]int) {
p[0] *= 2
p[1] *= 2
p[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 main
import "fmt"
func changeValue(arr [3]*int) [3]*int {
d := 50
arr[1] = &d
return arr
}
func main() {
a := 10
b := 20
c := 30
arr := [...]*int {&a, &b, &c}
fmt.Printf("The value is %v\n", arr)
ret := changeValue(arr)
fmt.Printf("The value is %v", ret)
}