go中结构体指针可直接用点号访问字段,无需显式解引用;传参需显式取地址;nil指针访问会panic,须提前判空;嵌套指针链式访问需确保每层非nil。

用 & 获取结构体指针后,直接用点号访问字段
Go 中结构体指针不是必须解引用才能访问字段——编译器会自动处理。只要变量是 *T 类型(比如 *User),就能直接写 ptr.Name,无需写 (*ptr).Name。
常见错误是手动加括号和星号,比如 (*u).Name 虽然语法合法,但冗余且易出错;更糟的是误写成 *u.Name(运算符优先级导致等价于 *(u.Name),直接报错)。
- 正确写法:
userPtr := &User{Name: "Alice"}; fmt.Println(userPtr.Name) - 错误写法:
fmt.Println(*userPtr.Name)→invalid indirect of userPtr.Name (type string) - 场景:传参给需要修改原结构体的函数时,必须传
&v,否则函数内修改的是副本
传指针进函数修改原结构体,别忘了取地址
如果函数签名是 func updateUser(u *User),调用时必须显式传地址。Go 不会自动取址,哪怕参数是结构体指针类型。
容易踩的坑是传值进去还指望改原值,比如 updateUser(u)(u 是 User 类型),函数里所有修改都只作用于副本,调用方完全无感。
- 正确:
updateUser(&u),u是User变量 - 错误:
updateUser(u),编译不报错但逻辑失效 - 性能影响:大结构体传指针避免拷贝,小结构体(如两个
int)传值反而更快,不必强求指针
nil 指针访问字段会 panic,得先判空
结构体指针可能是 nil,尤其是从 map 查找、函数返回或 JSON 解析失败时。直接访问字段会触发 panic: runtime error: invalid memory address or nil pointer dereference。
不能依赖 defer/recover 来兜底,而应在访问前检查是否为 nil。Go 没有安全导航操作符(如 JS 的 ?. ),必须手动判断。
- 正确:
if u != nil { fmt.Println(u.Name) } - 错误:
fmt.Println(u.Name)(当u为nil时崩溃) - 注意:
u == nil是合法比较,但u.Name == ""这类表达式在u为nil时不会短路,一定先崩
嵌套结构体中混用值和指针类型,字段访问行为一致
结构体字段本身可以是指针类型(如 Profile *Profile),也可以是值类型(如 Profile Profile)。无论哪种,只要该字段非 nil,都能用点号链式访问,Go 自动处理中间解引用。
例如 user.Profile.Address.City 能成立,前提是 user 非 nil、user.Profile 非 nil、user.Profile.Address 非 nil —— 缺一个就 panic。
- 字段定义示例:
type User struct { Profile *Profile },Profile是另一个结构体 - 安全写法:逐层判空,或封装为方法(如
u.ProfileCity()内部处理nil) - 不要假设“既然用了指针,就一定非 nil”——指针初始值就是
nil
nil,尤其在处理外部数据(API 响应、配置文件)时,看似简单的链式访问背后藏着好几个潜在 panic 点。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











