Skip to content

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) 分配零值并返回 *Tp := new(AGV)

6. JavaScript / TypeScript 对比

GoJS
显式 *T&对象隐式引用
无指针运算无指针概念
nil pointer dereference → panicnull/undefined 访问可能 undefined
值类型默认拷贝对象默认共享引用

只能类比理解「共享修改」,底层机制并不相同。


7. 常见错误

  1. nil 指针解引用 → panic
  2. 不需要指针时用指针 → 小 struct 值传递更简单
  3. 返回局部变量指针 → Go 逃逸分析,合法(与 C 不同)
  4. 混淆 *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 值接收者


学习导航

上一篇:function · 对应练习 · 下一篇:method