Map with Callback to 具有接收器的函数的语法

dh1*_*1tw 4 dictionary go

是否可以在 golang 中创建一个包含具有接收器的函数的地图?

我想完成以下工作

函数回调:

func (my *mystruct) doSometing(int parameter1){
// do something
}

func (my *mystruct) doAnotherThing(int parameter1){
// do something
}
Run Code Online (Sandbox Code Playgroud)

包含指向函数的指针的映射

var lookupMap = map[string]func(int){
    "action1" : doSomething,
    "action2" : doAnotherThing
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用,因为回调函数绑定到接收器。Go编译器说:

"undefined doSomething"
Run Code Online (Sandbox Code Playgroud)

我的问题:

创建映射的语法是什么,其中值是绑定到特定接收器的函数?

类似(伪代码):

var lookupMap = map[string]((*mystruct)func(int)){
}
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏!

icz*_*cza 5

使用方法值

您可以为此目的使用Method 值。方法值是具有隐式接收器的函数值。引用规范:方法值

如果表达式x具有静态类型T并且M在type的方法集中Tx.M则称为方法值。

因此,方法值的语法是x.M,例如,x是类型的值,M是方法的名称。这导致函数具有与没有接收器的方法相同的参数(和返回类型),因为接收器将与方法值一起保存并且是隐式的。

所以这意味着为您的doSometing()doAnotherThing()方法存储方法值,函数类型将是func (int)(无接收器)。

这是一个工作示例:

type mystruct struct {
    name string
}

func (my *mystruct) doA(i int) {
    fmt.Printf("[doA]: I'm %s, param is: %d\n", my.name, i)
}

func (my *mystruct) doB(i int) {
    fmt.Printf("[doB]: I'm %s, param is: %d\n", my.name, i)
}

func main() {
    my1 := &mystruct{"Bob"}
    my2 := &mystruct{"Alice"}
    lookupMap := map[string]func(int){
        "action1": my1.doA,
        "action2": my2.doB,
    }

    lookupMap["action1"](11)
    lookupMap["action2"](22)
}
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上试试):

[doA]: I'm Bob, param is: 11
[doB]: I'm Alice, param is: 22
Run Code Online (Sandbox Code Playgroud)

使用方法表达式

如果您不想将接收器保存在字典中(在方法值中),您可以使用Method 表达式

不同的是,在获取函数值时,不使用x.Mbut T.M,会得到一个函数值,具有相同参数(和返回类型)的函数类型,但接收器类型也会在参数中列表,并排在首位。请参阅Spec 中的引用:方法表达式

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

因此,在您的情况下,要使用的函数类型将如下所示: func(*mystruct, int)

此外,由于不会保存接收器,因此您必须在调用这些函数时提供它。

请参阅此工作示例(这是对第一个示例的修改):

type mystruct struct {
    name string
}

func (my *mystruct) doA(i int) {
    fmt.Printf("[doA]: I'm %s, param is: %d\n", my.name, i)
}

func (my *mystruct) doB(i int) {
    fmt.Printf("[doB]: I'm %s, param is: %d\n", my.name, i)
}

func main() {
    lookupMap := map[string]func(*mystruct, int){
        "action1": (*mystruct).doA,
        "action2": (*mystruct).doB,
    }

    my1 := &mystruct{"Bob"}
    my2 := &mystruct{"Alice"}
    lookupMap["action1"](my1, 11)
    lookupMap["action2"](my2, 22)
}
Run Code Online (Sandbox Code Playgroud)

输出是一样的(在Go Playground上试试):

[doA]: I'm Bob, param is: 11
[doB]: I'm Alice, param is: 22
Run Code Online (Sandbox Code Playgroud)

看到类似的问题:

golang - 将方法传递给函数

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