Types Go方法集&x2014;使用接收器T调用指针类型*T的方法

Types Go方法集&x2014;使用接收器T调用指针类型*T的方法,types,go,Types,Go,Go说: 任何其他类型T的方法集由接收器类型T的所有方法组成。相应指针类型*T的方法集是接收器*T或T的所有方法集(即,它还包含接收器类型T的方法集) 我的理解是:T有自己的方法集,而*T有自己的方法集加上T的方法集,因为它可以将receiver*T解引用到T并调用该方法。因此,我们可以使用变量类型为T的receiver*T调用某些方法 所以我决定验证我的逻辑: package main import ( "fmt" "reflect" ) type User struct{} f

Go说:

任何其他类型T的方法集由接收器类型T的所有方法组成。相应指针类型*T的方法集是接收器*T或T的所有方法集(即,它还包含接收器类型T的方法集)

我的理解是:T有自己的方法集,而*T有自己的方法集加上T的方法集,因为它可以将receiver*T解引用到T并调用该方法。因此,我们可以使用变量类型为T的receiver*T调用某些方法

所以我决定验证我的逻辑:

package main

import (
  "fmt"
  "reflect"
)

type User struct{}

func (self *User) SayWat() {
  fmt.Println(self)
  fmt.Println(reflect.TypeOf(self))
  fmt.Println("WAT\n")
}

func main() {
  var user User = User{}

  fmt.Println(reflect.TypeOf(user), "\n")

  user.SayWat()
}

我有点困惑。看起来我可以在T上调用方法“of*T”?我有一个更广泛的例子,这也让我困惑。是否存在相反的类型推断

是我遗漏了什么,还是我的逻辑不正确


谢谢

您不能在
T
上调用
*T
的方法,但编译器足够聪明,可以为您引用变量,有效地调用

(&user).SayWat()
解释如下:

调用:如果方法集(类型)为x,则方法调用x.m()有效 包含m,参数列表可以指定给的参数列表 M如果x是可寻址的,并且&x的方法集包含m,则x.m()是速记 对于(&x).m()

为了理解差异,您可以获取一个返回值(不可寻址):

失败并出现错误:

prog.go:40: cannot call pointer method on aUser()
prog.go:40: cannot take the address of aUser()

+1,正是我写的。顺便说一句,您可以为计数器示例编写
User{}.SayWat()
。您可以看到:
prog.go:40: cannot call pointer method on aUser()
prog.go:40: cannot take the address of aUser()