在Go中,指针是一个存储其他变量地址的变量。与某些语言不同,在Go中无法执行指针算术,这使它们更安全。指针在Go中常用于:
在Go中没有像C++那样的显式引用类型支持,但切片和映射本质上是引用的,通常按值传递。
package main import "fmt" type User struct { Name string } func changeNameByValue(u User) { u.Name = "瓦西亚" } func changeNameByPointer(u *User) { u.Name = "彼得" } func main() { user := User{Name: "伊万"} changeNameByValue(user) fmt.Println(user.Name) // 伊万 changeNameByPointer(&user) fmt.Println(user.Name) // 彼得 }
指针能否指向Go中的常量或文字?
正确答案: 不,在Go中不能直接对常量或文字取地址。只能对变量取地址:
x := 5 p := &x // 好 p2 := &10 // 编译错误
这常常与允许类似操作的语言混淆。
故事
在一个项目中,开发人员试图传递切片元素的引用,以为可以通过指针安全地修改切片。但错误地认为切片本身包含一个指针,然而在调用append()后,底层数组的地址会改变,修改不总是反映在原始数据上。这导致了难以捉摸的错误(数据“丢失”)。
故事
在项目中,在循环内创建了一个指向局部变量的指针列表,循环结束后,所有指针都指向同一个变量(循环迭代变量)。只有在生产环境崩溃后才发现了错误。
故事
开发人员错误地认为,指针赋值会释放内存中的前一个对象,并显式将指针赋值为nil,期待GC立即生效。实际上,在Go中,垃圾收集器自行决定何时清理对象,忽略提早置空引用。导致在期待及时释放内存的地方发生了内存泄漏。