首页 文章

Go方法集 - 指针类型的调用方法* T与接收方T

提问于
浏览
2

spec说:

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

我理解为:T有自己的方法集,而* T有自己的方法集加上T的方法集,因为它可以取消引用接收器* T到T并调用方法 . 因此,我们可以使用变量类型为T的接收器* 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()
}

http://play.golang.org/p/xMKuLzUbIf

我有点困惑 . 看起来我可以在T上调用方法"of *T"?我有一个更广泛的例子http://play.golang.org/p/RROPMj534A,这也让我感到困惑 . 是否有一些相反的类型推断?

我错过了什么,或者我的逻辑是不正确的?

谢谢!

1 回答

  • 7

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

    (&user).SayWat()
    

    这是解释here

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

    要了解差异,您可以获取返回值(不可寻址):

    func aUser() User {
        return User{}
    }
    
    ...
    
    aUser().SayWat()
    

    失败错误:

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

    http://play.golang.org/p/HOTKiiOK7S

相关问题