指针
什么是指针
指针是一种存储变量内存地址(Memory Address)的变量
指针的声明
指针变量的类型为 *T,该指针指向一个 T 类型的变量。
& 取地址符号 * 放在类型旁边,表示指向这个类型的指针 * 放在变量旁边,表示解引用(反解)
package main import "fmt" func main() { a:=10 var b *int=&a //b就是一个指针,指向int类型的指针。也可以用这种方法写b:=&a fmt.Println(b) //0xc00000a0b8 fmt.Println(*b) //10 反解 }
指针的零值(nil类型,是引用传递)
package main import "fmt" func main() { var a *int fmt.Println(a) //<nil> }
向函数传递指针参数 (因为传递的是地址,所以修改值会把原数据也修改了)
package main import "fmt" func main() { a:=10 b:=&a test3(b) fmt.Println(a) //11 } func test3(b *int) { *b++ fmt.Println(*b) //11 } #结果 11 11
不要向函数传递数组的指针,而应该是使用切片
假如我们想要在函数内修改一个数组,并希望调用函数的地方也能得到修改后的数组,一种解决方案是把一个指向数组的指针传递给这个函数
package main import "fmt" func main() { //传递数组的指针 var a[4]int //数组 test4(&a) //传递数组指针 fmt.Println(a) } func test4(a *[4]int) { (*a)[0]=999 //在这里修改a中的值,也会修改原来的值,因为传递的是地址 fmt.Println(*a) } #结果 [999 0 0 0] [999 0 0 0]
这种方式向函数传递一个数组指针参数,并在函数内修改数组。尽管它是有效的,但却不是 Go 语言惯用的实现方式。我们最好使用切片来处理
接下来我们用[切片]来重写之前的代码。
package main import "fmt" func main() {
//传递切片 var a[4]int test5(a[:]) fmt.Println(a) } func test5(a []int) { //传递切片参数 a[0]=999 //修改值 fmt.Println(a) } #结果 [999 0 0 0] [999 0 0 0]
这两种方式结果都一样。所以别再传递数组指针了,而是使用切片。上面的代码更简洁
Go不支持指针运算
Go 并不支持其他语言(例如 C)中的指针运算