如何在Golang中模拟C++的引用(&)参数_使用指针实现

1次阅读

go语言无引用类型,仅支持指针;必须传*T修改值类型变量、避免大结构体拷贝、实现可修改方法接收者;需警惕nil解引用、切片元素地址失效及返回局部变量地址等陷阱。

如何在Golang中模拟C++的引用(&)参数_使用指针实现

Go 里没有引用类型,只有指针

Go 语言从设计上就**不支持 c++ 那种语法层面的引用(&)**,也没有引用语义的变量声明。所谓“模拟”,本质是用 *T 指针显式传递地址,并在函数内通过 *p 解引用修改原值。这不是语法糖,而是明确的内存操作——你得自己管好生命周期、空指针和所有权边界。

什么时候必须传 *T 而不是 T

当函数需要修改调用方的变量值,且该变量是值类型(intStruct[3]int 等)时,必须传指针。传值只会拷贝一份,改了也没用。

  • func increment(x int) { x++ } → 调用后原变量不变
  • func increment(x *int) { *x++ } → 必须传 &v,才能改 v
  • 结构体较大时,传 *S 避免拷贝开销(哪怕你不修改它)
  • 方法接收者用指针(func (s *S) SetName(n String))才能修改字段

常见错误:nil 指针解引用和意外共享

Go 不做空指针防护,*p 前不检查 p == nil 就 panic;另外,多个地方持有同一指针,可能引发竞态或意料外的修改。

  • nil*string 参数却直接 *s = "x"panic: runtime Error: invalid memory address or nil pointer dereference
  • 对切片元素取地址:&slice[i] 在 slice 扩容后可能失效(底层数组被替换)
  • 把局部变量地址返回:func bad() *int { x := 42; return &x } → 返回后 x 已出,行为未定义(Go 编译器通常会逃逸分析并分配到,但逻辑上仍危险)

和 C++ 引用的关键差异点

C++ 的 int& r = x 是别名,不可重绑定、不能为空;Go 的 *int 是可变地址、可为 nil、可重新赋值指向别处——语义更接近 C 的指针,而非 C++ 引用。

立即学习go语言免费学习笔记(深入)”;

  • C++ 引用参数隐式传递,Go 指针参数必须显式写 &v
  • C++ 可以 const int& r = x 实现只读引用;Go 没有 const,靠约定或封装(如只暴露 getter 方法)
  • 结构体字段不能是指针类型“引用”另一个字段(Go 不支持字段引用),只能存值或指针
  • 接口值本身是 (type, value) 二元组,传接口时若底层是大对象,仍可能触发拷贝 —— 这点容易被忽略
text=ZqhQzanResources