func() 在自定义结构类型上时的接口转换

Interface conversion when func() is on a custom struct type

我有完美运行的代码:

package main

import (
    "fmt"
)

var funcMap = map[string]interface{}{
    "hello": hello,
}

func main() {
    callDynamically("hello")
}

func callDynamically(name string) {
    funcMap[name].(func())()
}

func hello() {
    fmt.Println("hello")
}

但是如果我尝试像这样在我的结构类型上定义 hello(),我的大脑就会发疯:

package main

import (
    "fmt"
)

type myType struct {
    field1  string
    field2  string
    funcMap map[string]interface{}
}

func main() {
    mt := &myType{
        field1: "qwe",
        field2: "asd",
        funcMap: map[string]interface{}{
            "hello": (*myType).hello,
        },
    }

    mt.callDynamically("hello")
}

func (mt *myType) callDynamically(name string) {
    mt.funcMap[name].(func())()
}

func (mt *myType) hello() {
    fmt.Println("hello")
}

https://play.golang.org/p/pPvmaL22_Td

我收到这个错误:

panic: interface conversion: interface {} is func(*main.myType), not func()

当 my 函数是在自定义结构类型上定义时,我真的无法理解如何在 callDynamically 中调用 func()

有什么帮助吗?

谢谢。

Go 中的方法只是添加了一些语法糖的函数。接收者实际上是函数的第一个参数,因此 (*myType).hello - 来自类型的方法 - 实际上是 func(*myType);它没有要调用的接收器实例,因此如果不显式提供一个作为函数参数就无法调用它。 in the spec on Method Expressions.

如果您改为从该类型的 实例 中获取方法,则该参数已经被填充,因此:

foo := &myType{}
fn := foo.hello

这里 fn 是一个 func() 因为它已经有一个实例用作接收者。这涵盖了 in the spec on Method Values.

struct初始化后将struct实例的函数添加到funcMap

func main() {
    mt := &myType{
        field1: "qwe",
        field2: "asd",
        funcMap: map[string]interface{}{},
    }
    mt.funcMap["hello"] = mt.hello

    mt.callDynamically("hello")
}