go-基于指针对象的方法-编译器隐式取地址
⏺ Go 编译器隐式取地址的完整细节
场景回顾
ScaleBy 是指针接收器方法,按理说只有 *Point 才能调用:
1 | func (p *Point) ScaleBy(factor float64) { |
但你可以这样写:
1 | p := Point{1, 2} |
这是因为编译器帮你做了隐式转换,实际执行的是:
1 | (&p).ScaleBy(2) // 编译器自动取地址 |
隐式转换其实有两个方向
方向一:值调用指针方法 → 自动取地址 &
1 | p := Point{1, 2} |
**方向二:指针调用值方法 → 自动解引用 ***
1 | pptr := &Point{1, 2} |
总结就是:不管你拿着值还是指针,编译器都会自动帮你匹配到正确的接收器类型。
关键限制:必须能取到地址
隐式取 & 有一个前提——变量必须是可寻址的(addressable)。
1 | // ✅ 变量 — 可寻址 |
为什么临时值不行? 因为 Point{1, 2} 是一个没有存在任何地方的临时值,没有内存地址可取。
取地址的前提是这个值得”住”在某个地方(变量、字段、元素)。
完整示意
1 | type Point struct{ X, Y float64 } |
| 你手里有 | 方法需要 | 编译器做什么 |
|---|---|---|
| Point | Point | 直接调 |
| Point | *Point | 自动 & 取地址 |
| *Point | Point | 自动 * 解引用 |
| *Point | *Point | 直接调 |
一句话理解
Go 编译器的态度是:你别管值和指针的转换了,只要变量有地址,我帮你搞定。
这就是为什么日常写 Go 代码时,你几乎不需要显式写 (&p).Method() 这种丑陋的语法。
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.