指针存储地址而普通变量存储值,核心区别在于值传递与地址传递;普通变量赋值和传参时复制值,互不影响,而指针通过解引用可修改原变量,实现共享和高效传参,适用于大对象和需修改原值的场景,但需注意空指针和解引用开销,掌握指针本质有助于编写高效安全的go代码。

在 Go 语言(Golang)中,指针和普通变量是两种不同的数据操作方式,它们的核心区别在于如何存储和访问数据,尤其是涉及内存地址与值的处理方式。理解它们的差异,有助于写出更高效、更安全的代码。
1. 普通变量:直接存储值
普通变量是我们最常使用的类型,它直接在内存中保存实际的数据值。
var a int = 10
这段代码的意思是:定义一个整型变量
a
,并将值
10
存入分配给
a
的内存空间中。
立即学习“go语言免费学习笔记(深入)”;
特点:存储的是“值”本身。每次赋值或传参时,都会复制整个值。不同变量即使值相同,也各自拥有独立的内存空间。
b := a // 将 a 的值复制给 bb = 20 // 修改 b 不会影响 a
此时
a
仍然是 10,因为
b
只是得到了
a
的副本。
2. 指针变量:存储内存地址
指针是一种变量,它不直接存储值,而是存储另一个变量的内存地址。
var p *int = &a
这里:
&a
表示取变量
a
的内存地址。
*int
是指向整型的指针类型。
p
的值是
a
的地址,而不是
a
的值。
通过
*p
可以“解引用”指针,访问它指向的值:
*p = 30 // 修改 p 指向的值,即 a 的值fmt.Println(a) // 输出 30
特点:存储的是“地址”,不是值。解引用(
*p
)才能访问或修改目标值。多个指针可以指向同一个变量,实现共享和间接修改。
3. 内存层面的差异对比
存储内容实际的值(如 10)另一个变量的内存地址(如 0xc000012080)内存占用根据类型决定(int 占 8 字节)固定为指针大小(64 位系统通常 8 字节)赋值行为值拷贝地址拷贝(或 nil)函数传参效率大对象复制开销大只传地址,高效是否可修改原值否(除非是 slice/map/channel)是,通过解引用可修改原变量
举个例子说明传参差异:
func modifyByValue(x int) { x = 100}func modifyByPointer(x *int) { *x = 100}a := 10modifyByValue(a) // a 不变modifyByPointer(&a) // a 变成 100
4. 指针的常见用途
避免大结构体复制:结构体很大时,传指针远比传值高效。修改函数外的变量:通过指针实现“引用传递”效果。动态内存分配:
new()
返回指向新分配内存的指针。实现数据结构:如链表、树等需要节点间引用。
type Person struct { Name string Age int}p1 := Person{"Alice", 25}p2 := &p1 // p2 是指针,指向 p1p2.Age = 30 // 修改通过指针fmt.Println(p1.Age) // 输出 30
5. 注意事项与常见误区
空指针风险:未初始化的指针是
nil
,解引用会 panic。
var ptr *intfmt.Println(*ptr) // 运行时错误:invalid memory address
不要返回局部变量的地址:Go 会自动逃逸分析,但要避免误解。
func bad() *int { x := 10 return &x // 虽然合法(Go 做了逃逸分析),但逻辑要小心}
指针并不总是更快:小类型(如 int、bool)传值通常比传指针更高效,因为避免了解引用开销。
总结
普通变量直接持有值,安全简单,适合大多数场景。指针持有地址,支持间接访问和修改,适合共享数据、大对象传递。关键区别在于:值传递 vs 地址传递,复制开销 vs 解引用风险。
掌握指针的本质——“指向内存位置的标签”,就能更好理解 Go 中数据是如何被组织和操作的。基本上就这些,不复杂但容易忽略细节。
以上就是Golang指针与普通变量有何区别 解析内存地址与值存储的差异的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1401616.html
微信扫一扫
支付宝扫一扫