Go语言中的指针语法和C++一脉相承,都是用*
作为符号,虽然语法上接近,但是实际差异不小。
指针(pointer)概念在 Go 语言中被拆分为两个核心概念:
- 类型指针,允许对这个指针类型的数据进行修改。传递数据使用指针,而无须拷贝数据。类型指针不能进行偏移和运算。
- 切片,由指向起始元素的原始指针、元素数量和容量组成。
切片比原始指针具备更强大的特性,更为安全。切片发生越界时,运行时会报出宕机,并打出堆栈,而原始指针只会崩溃
受益于这样的约束和拆分,Go 语言的指针类型变量拥有指针的高效访问,但又不会发生指针偏移,从而避免非法修改关键性数据问题。同时,垃圾回收也比较容易对不会发生偏移的指针进行检索和回收。
指针在Go中是“安全”的,指针无法指向任意的内存区域,缓冲区溢出的问题不会发生。但注意,解引用一个空指针同样能导致Go程序崩溃
一个简单的实现
package main import "fmt" func Add(i int ) { i=0; } func update(i *int) { *i=0 } func main() { i := 1 update(&i) fmt.Println("update:", i) } 结果:update: 0
从指针获取指针指向的值
在对普通变量使用&
操作符取地址获得这个变量的指针后,可以对指针使用*
操作,也就是指针取值,代码如下。
package main import "fmt" func main() { // 准备一个字符串类型 var house = "str2019" // 对字符串取地址, ptr类型为*string ptr := &house // 对指针进行取值操作 value := *ptr // 指针取值后就是指向变量的值 fmt.Printf("value: %s\n", value) } 结果:value: str2019