Go语言指针是什么_Golang指针基本概念解析

6次阅读

go指针是内存地址值,声明用T、取址用&x、解引用用p;需确保可寻址和非nil;传指针避免复制且可修改原值;new()零值分配,&T{}支持初始化;返回局部变量指针安全因逃逸分析;小结构体值传递更优。

Go语言指针是什么_Golang指针基本概念解析

Go语言指针就是变量的内存地址本身,不是值,也不是“引用”这种抽象概念——它就是一个实实在在的、可传递、可存储、可比较的地址值。

怎么声明和用对 &*

声明指针用 *T,取地址用 &x,解引用用 *p。这三个符号必须严格对应,少一个或错位置就编译失败或 panic。

  • & 只能作用于「可寻址的变量」:比如 name := "alice"&name 合法;但 &"alice"&(1+2) 直接报错 —— 字面量和临时计算结果不可取址
  • * 解引用前必须确保指针非 nil,否则运行时 panic:var p *int; fmt.Println(*p) 会崩溃
  • 结构体字段访问自动解引用:person := &Person{Name: "Tom"}; fmt.Println(person.Name) 等价于 (*person).Name,不用写 *

为什么函数传参要用 *T 而不是 T

因为 Go 默认是值传递:传 T 就等于把整个值拷贝一份进函数;传 *T 只拷贝 8 字节(64 位系统)的地址,还能改原值。

  • 改结构体字段:传 *Person 才能让 SetName() 真正修改调用方的 Person 实例
  • 避免大对象复制:一个含 1MB 字段的 Struct,传值 ≈ 每次调用 malloc + copy;传指针几乎零开销
  • 注意副作用:多个 goroutine 共享同一 *T 时,字段修改不加锁会引发数据竞争

new()&T{} 有什么区别

两者都返回 *T,但语义和初始化方式不同:前者只做零值分配,后者可带字段初始化。

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

  • p := new(int) → 分配一个 int 内存,值为 0,返回 *int
  • p := &Person{Name: "Bob", Age: 25} → 构造并初始化结构体,再取址,更常用也更直观
  • new() 几乎只用于基本类型或极简场景;日常优先用 &T{...},语义清晰且支持字段赋值

返回局部变量的指针安全吗?

安全。Go 编译器有逃逸分析,会自动把本该在上分配的变量提升上,只要指针被返回,底层内存就不会被回收。

  • 例如:func NewConfig() *Config { c := Config{Port: 8080}; return &c } 是完全合法且推荐的惯用法
  • 不要手动模拟“栈上分配 + 返回地址”的 C 风格操作,Go 不需要也不鼓励你操心这个
  • 真正要警惕的不是“能不能返回”,而是“要不要返回”:如果调用方不需要共享状态,返回值更简单、更无副作用

最容易被忽略的一点:指针不是银弹。小结构体(比如两个 int 字段)、纯计算函数、无状态转换逻辑,用值传递反而更清晰、更利于内联和逃逸优化。别为了“看起来高效”而滥用指针。

text=ZqhQzanResources