Skip to content

method

Phase 01 — Go Fundamentals · 知识点 13


1. 学习目标

  • 为 struct 定义 method
  • 区分值接收者 (a AGV) 与指针接收者 (a *AGV)
  • 知道何时必须用指针接收者
  • 理解 method 不是 class 的 method,无继承

2. 为什么需要

method 把数据和操作绑在一起:agv.Move()agv.IsOverspeed()。比独立函数 Move(agv) 更符合面向对象风格,但 Go 的 method 是语法糖,底层仍是函数。


3. 核心概念

go
type AGV struct {
    ID    string
    Speed float64
}

// 值接收者 — 操作副本
func (a AGV) String() string {
    return fmt.Sprintf("%s (%.1f m/s)", a.ID, a.Speed)
}

// 指针接收者 — 可修改原对象
func (a *AGV) SetSpeed(s float64) {
    a.Speed = s
}

func (a *AGV) IsOverspeed(max float64) bool {
    return a.Speed > max
}
接收者何时用
(a AGV)不修改 struct、小 struct、需要副本
指针 (a *AGV)修改 struct、大 struct、保持一致性

惯例:如果一个 method 用指针接收者,同一类型的所有 method 都用指针接收者。


4. 基础语法

go
package main

import "fmt"

type AGV struct {
    ID    string
    X, Y  float64
    Speed float64
}

func (a *AGV) Move(dx, dy float64) {
    a.X += dx
    a.Y += dy
}

func (a AGV) DistanceToOrigin() float64 {
    return math.Sqrt(a.X*a.X + a.Y*a.Y)
}

func main() {
    agv := &AGV{ID: "AGV-001", X: 3, Y: 4}
    fmt.Println(agv.DistanceToOrigin())  // 5
    agv.Move(1, 1)
    fmt.Printf("%+v\n", agv)
}

Go 自动取地址:agv.Move() 即使 agv 是值也会自动 (&agv).Move()


5. 代码解析

  • method 是带接收者的函数:func (receiver Type) Name() {}
  • 非 struct 类型也可有 method(如 type MyInt int
  • method set:*T 的 method set 包含 *TT 的 method;T 的 method set 只含 T

6. JavaScript / TypeScript 对比

Go methodJS class
定义在 type 外定义在 class 内
无 this 绑定问题需注意 this
无继承extends 继承
值/指针接收者显式对象总是引用

7. 常见错误

  1. 值接收者修改字段无效 → 改用指针接收者
  2. nil 指针调用 method → 可以,method 内需检查 nil
  3. 混用值/指针接收者 → 团队风格不一致
  4. 过度 OOP → Go 倾向小 struct + 简单 method

8. 实际应用

go
func (a *AGV) ToJSON() ([]byte, error) {
    return json.Marshal(a)
}

func (a *AGV) UpdateFromTelemetry(x, y, speed float64) {
    a.X, a.Y, a.Speed = x, y, speed
}

数字孪生中,设备 struct + method 构成领域模型,后续 interface 实现多态。


9. 深入理解

method 是编译期绑定,非 virtual dispatch(除非通过 interface)。这是 Go 与 Java/C++ 虚函数的本质区别。


10. 练习

  • L1:值接收者 String() method
  • L2:指针接收者 SetSpeed / Move
  • L3:IsOverspeed / DistanceToOrigin
  • L4:AGV 完整 method set

11. 学习检查

  • [ ] 值接收者与指针接收者区别?
  • [ ] 修改字段该用哪种接收者?
  • [ ] nil 指针能调 method 吗?

12. 下一步

Phase 02 interface:method set 与多态


学习导航

上一篇:pointer · 对应练习 · 下一篇:Go Interface