为什么typeof(method)不返回reflect.Method实例?

Ale*_*lex 2 reflection methods types go

假设我有Foo结构,其方法定义如下:

type Foo struct {
    Name string
}

func (f *Foo) Get(a int, b string) (string, error) {
    return f.Name, nil
}
Run Code Online (Sandbox Code Playgroud)

如果我写

obj := &Foo{}
t := reflect.TypeOf(obj.Get)
Run Code Online (Sandbox Code Playgroud)

t.Kind()返回reflect.Func,显然我无法访问Get我从“属于” Foo结构中提取类型信息的函子,即接收方是Foo类型,甚至没有出现在参数中。

我想这是故意的,我想念一些有关函数的基本知识,这些函数使语言作者丢弃了应用于方法引用的typeof操作的接收者信息。

我有两个问题:

  1. 我是正确的,没有办法在TypeOf上面的调用中获取代码片段中的接收者类型吗?
  2. 如果我想将有关方法的反射信息传递给打算分析功能和相关接收者的代码(实质上是方法),我有什么选择?

尝试自己回答第二个问题,并根据我在官方文档中看到的内容,看来我唯一的选择是传递TypeOf(receiver)和TypeOf(receiver.method)或TypeOf(receiver)以及接收方的方法名称。

icz*_*cza 5

如mkopriva所述,您拥有的是方法值obj.Get。方法值是一个函数,其签名与没有接收方类型的方法的签名相同:

如果表达式x具有静态类型T并且M方法的类型集中Tx.M则称为方法值。方法值x.M是可以使用与方法调用相同的参数x.M调用的函数值。在计算方法值期间对表达式x进行评估并保存;然后,保存的副本将在任何调用中用作接收者,以后可能会执行。

如果使用方法表达式(而不是方法值),则接收器类型将“显示”在参数列表中(始终是第一个):

fmt.Println(reflect.TypeOf((*Foo).Get))
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上尝试):

func(*main.Foo, int, string) (string, error)
Run Code Online (Sandbox Code Playgroud)

方法表达式:

如果M在type 的方法集中TT.M则是可作为常规函数调用的函数,该函数具有与作为M 该方法的接收者的附加参数作为前缀的相同参数。

查看相关问题:

golang-函数的传递方法

方法接收器上的golang函数别名