Go中无引用类型,所有传参均为值传递;指针通过定义、&取地址,用于修改原值或避免大对象拷贝;slice、map、channel赋值时传递的是包含指针的结构体副本,共享底层数据,表现类似引用;函数中修改基本类型需传指针,而map、slice元素可直接修改,但重新分配需传指针或返回新值;new(T)返回零值T,&T{}可初始化具体值。

在Go语言中,指针和引用是两个容易混淆但又非常关键的概念。理解它们的区别与联系,对写出高效、安全的代码至关重要。
指针:直接操作内存地址
Go中的指针是一个变量,它存储另一个变量的内存地址。通过指针可以间接读取或修改该地址上的值。使用*定义指针类型,用&取地址,用*解引用。
例如:
x := 10
p := &x // p 是 *int 类型,指向 x 的地址
*p = 20 // 通过 p 修改 x 的值,现在 x 变为 20
指针常用于函数参数传递,避免大对象拷贝,提升性能。
立即学习“go语言免费学习笔记(深入)”;
引用类型:slice、map、channel 的本质
Go中没有传统意义上的“引用变量”,但有引用语义的类型,如 slice、map、channel。这些类型的底层数据结构包含指向堆上数据的指针,因此赋值或传参时,虽然传递的是值(拷贝),但拷贝的是包含指针的结构体,所以多个变量仍可影响同一份底层数据。
比如:
s1 := []int{1, 2, 3}
s2 := s1
s2[0] = 99 // s1[0] 也会变成 99
这并不是因为s1被“引用”了,而是s1和s2共享底层数组。这种行为类似引用,但本质仍是值传递——传递的是指向底层数组的指针的副本。
函数传参:何时需要指针?
基本类型(int、string等)和小结构体通常按值传递即可。但如果想在函数内修改原变量,或传递大型结构体以避免开销,应使用指针。
示例:
func updatePerson(p *Person) {
p.Name = “Alice”
}
调用updatePerson(&person)后,原始person会被修改。而如果传值,则函数内修改无效。
对于map和slice,函数内可以直接修改其元素,不需要传指针。但如果要重新分配(如用make创建新slice并赋值给形参),则需传**指针的指针**或返回新值。
常见误区与最佳实践
不要误以为map或slice本身就是“引用类型”就一定能在函数中改变其指向。例如:
func reset(s []int) {
s = nil
}
// 调用后原slice不变
正确做法是返回新slice,或传*[]int。
实践中建议:
结构体修改需求明确时使用指针传参避免过度使用指针,增加代码复杂性和GC压力理解“引用语义”不等于“引用类型”,Go所有传参都是值传递new() 和 & 的区别:new(T) 返回* T并清零;&T{} 可初始化具体值
基本上就这些。掌握指针和引用语义的关键,在于理解Go的值传递机制以及各类型底层的数据结构。不复杂但容易忽略细节。
以上就是Golang如何理解指针与引用_Golang 指针引用使用实践的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1426360.html
微信扫一扫
支付宝扫一扫