外观
pointer
Phase 01 — Go Fundamentals · 知识点 12
1. 学习目标
- 理解指针
*T和取地址& - 知道指针用于修改原值、避免大 struct 拷贝
- 理解 Go 有指针但无指针运算
- 区分 nil 指针与零值
2. 为什么需要
JavaScript 对象默认是引用传递,Go struct 默认是值拷贝。要在函数内修改 AGV 状态、共享同一设备对象,必须使用指针。
这是前端开发者学 Go 必须跨越的门槛——Go 有指针,但比 C/C++ 简单得多。
3. 核心概念
go
var x int = 10
var p *int = &x // p 是指向 x 的指针
fmt.Println(*p) // 10,解引用
*p = 20 // 通过指针修改 x
fmt.Println(x) // 20| 语法 | 含义 |
|---|---|
*T | 指向 T 的指针类型 |
&v | 取 v 的地址 |
*p | 解引用,获取指针指向的值 |
nil | 零值指针,未指向任何对象 |
4. 基础语法
go
type AGV struct {
ID string
Speed float64
}
func setSpeed(a *AGV, speed float64) {
a.Speed = speed // 修改原对象,等价于 (*a).Speed
}
func main() {
agv := AGV{ID: "AGV-001", Speed: 1.0}
setSpeed(&agv, 2.5)
fmt.Println(agv.Speed) // 2.5
var p *AGV = nil
if p != nil {
fmt.Println(p.ID)
}
}5. 代码解析
a *AGV接收指针,修改字段影响原 struct- Go 自动解引用:
a.Speed等价于(*a).Speed new(T)分配零值并返回*T:p := new(AGV)
6. JavaScript / TypeScript 对比
| Go | JS |
|---|---|
显式 *T 和 & | 对象隐式引用 |
| 无指针运算 | 无指针概念 |
| nil pointer dereference → panic | null/undefined 访问可能 undefined |
| 值类型默认拷贝 | 对象默认共享引用 |
只能类比理解「共享修改」,底层机制并不相同。
7. 常见错误
- nil 指针解引用 → panic
- 不需要指针时用指针 → 小 struct 值传递更简单
- 返回局部变量指针 → Go 逃逸分析,合法(与 C 不同)
- 混淆
*T是指针类型 vs 解引用 → 看上下文
8. 实际应用
go
func updatePosition(a *AGV, x, y float64) {
a.X = x
a.Y = y
}
// 连接池、缓存中存 *AGV 而非 AGV,避免拷贝
devices := map[string]*AGV{
"AGV-001": {ID: "AGV-001"},
}WebSocket 连接管理器通常存 map[string]*Client。
9. 深入理解
- Go 有指针,无指针算术
- 逃逸分析决定变量分配在栈还是堆
*T的零值 nil 不等于指向零值的指针
10. 练习
- L1:& 和 * 基本操作
- L2:指针修改 struct
- L3:nil 指针检查
- L4:map 存 *AGV 并更新
11. 学习检查
- [ ] 何时用指针参数?
- [ ] nil 指针解引用会怎样?
- [ ] Go 与 C 指针有何不同?
12. 下一步
→ method:指针接收者 vs 值接收者