去接收器方法调用语法混淆

Jib*_*ran 4 go

我只是通过Effective GoPointers vs. Values部分阅读,接近结尾它说:

有关接收器的指针与值的规则是可以在指针和值上调用值方法,但只能在指针上调用指针方法.这是因为指针方法可以修改接收器; 在值的副本上调用它们将导致丢弃这些修改.

为了测试它,我写了这个:

package main

import (
  "fmt"
  "reflect"
)

type age int

func (a age) String() string {
  return fmt.Sprintf("%d yeasr(s) old", int(a))
}

func (a *age) Set(newAge int) {
  if newAge >= 0 {
    *a = age(newAge)
  }
}

func main() {
  var vAge age = 5
  pAge := new(age)

  fmt.Printf("TypeOf =>\n\tvAge: %v\n\tpAge: %v\n", reflect.TypeOf(vAge),
    reflect.TypeOf(pAge))

  fmt.Printf("vAge.String(): %v\n", vAge.String())
  fmt.Printf("vAge.Set(10)\n")
  vAge.Set(10)
  fmt.Printf("vAge.String(): %v\n", vAge.String())

  fmt.Printf("pAge.String(): %v\n", pAge.String())
  fmt.Printf("pAge.Set(10)\n")
  pAge.Set(10)
  fmt.Printf("pAge.String(): %v\n", pAge.String())
}
Run Code Online (Sandbox Code Playgroud)

它编译,即使文档说它不应该,因为指针方法Set()不应该通过值var来调用vAge.我在这里做错了吗?

Ros*_*ght 9

这是有效的,因为vAge是可寻址的.请参阅语言规范下的Calls中的最后一段:

如果方法集x(类型)x包含m并且参数列表可以分配给m的参数列表,则方法调用xm()有效.如果x是可寻址的并且&x的方法集包含m,则xm()是(&x).m()的简写.