Go中无引用类型,只有指针;&操作符返回指针,用于解引用;“传引用”实为误称,修改原变量需显式传 T并解引用赋值。
Go 里没有引用类型,只有指针
Go 语言中不存在 C++ 那种语法层面的「引用(reference)」,& 操作符永远返回一个指针,* 永远用于解引用。所谓「传引用」只是开发者对「传指针」行为的误称。函数参数若想修改原始变量,必须显式传入 *T 类型,并在函数内用 *p = ... 赋值。
常见错误现象:func modify(x int) { x = 42 } 不会改变调用方的变量;而 func modify(x *int) { *x = 42 } 才会。
- 结构体较大时,传
*S比传S更节省内存和复制开销 - 方法接收者用指针(
func (s *S) Method())才能修改字段;值接收者(func (s S) Method())只能读或改副本 - 切片、map、channel 本身是引用类型(底层含指针),但它们的变量仍是值——所以
append后需重新赋值,否则调用方看不到新元素
new() 和 & 的区别:何时该用哪个
new(T) 返回 *T,且将内存置零;&t 取已有变量 t 的地址。二者语义不同,不能混用。
使用场景:
- 需要一个零值指针且无现成变量时,用
new(T)—— 如ptr := new(int)等价于var tmp int; ptr := &tmp - 已有变量要传给函数或赋给结构体字段,直接用
&v—— 更直观、更常见 -
new([]int)返回*[]int(指向 nil 切片的指针),不是你想要的可 append 的切片;此时应写&[]int{}[0]或更稳妥地用make+&
nil 指针解引用 panic 的典型场景
Go 运行时会在解引用 nil 指针时 panic,错误信息为 panic: runtime error: invalid memory address or nil pointer dereference。这不是编译错误,容易漏测。