8

在某些情况下,我有几种方法(如添加、删除等)。然而,随着时间的推移,案例的数量正在增加,而我的开关案例也越来越长。所以我想我会创建一个方法图,比如Go map of functions;这里函数的映射是微不足道的。但是,是否可以在 Go中创建方法映射?

当我们有一个方法时:

func (f *Foo) Add(a string, b int) { }

下面的语法创建编译时错误:

actions := map[string]func(a, b){
        "add": f.Add(a,b),
}

是否可以在 Go 中创建方法映射?

4

4 回答 4

10

是的。目前:

actions := map[string]func(a string, b int){
        "add": func(a string, b int) { f.Add(a, b) },
}

稍后:见 guelfi 提到的 go11func 文档。

于 2013-02-26T13:35:04.803 回答
2

目前无法将接收器和方法存储在单个值中(除非将其存储在结构中)。这目前正在进行中,它可能会随着 Go 1.1 的变化而改变(参见http://golang.org/s/go11func)。

但是,您可以将方法分配给函数值(没有接收器)并稍后将接收器传递给该值:

package main

import "fmt"

type Foo struct {
    n int
}

func (f *Foo) Bar(m int) int {
    return f.n + m
}

func main() {
    foo := &Foo{2}
    f := (*Foo).Bar
    fmt.Printf("%T\n", f)
    fmt.Println(f(foo, 42))
}

这个值可以像其他任何东西一样存储在地图中。

于 2013-02-26T13:25:40.643 回答
0

您可以使用方法表达式执行此操作:

https://golang.org/ref/spec#Method_expressions

但是,这使得函数将接收者作为第一个参数:

actions := map[string]func(Foo, string, int){
  "add": Foo.Add
}

func(*Foo, string, int)同样,您可以使用签名获得一个函数(*Foo).Add

于 2020-02-05T01:04:18.393 回答
0

如果您想使用指针类型 Foo 作为接收者,例如:

func (f *Foo) Add(a string, b int) { }

然后您可以将字符串映射到 (*Foo, string, int) 的函数,如下所示:

var operations = map[string]func(*Foo, string, int){
    "add": (*Foo).Add,
    "delete": (*Foo).Delete,
}

然后你会用它作为:

var foo Foo = ...
var op string = GetOp() // "add", "delete", ...
operations[op](&foo, a, b)

whereGetOp()以字符串形式返回操作,例如来自用户输入。 a并且b是方法的字符串和 int 参数。

这假定所有方法都具有相同的签名。它们也可以具有相同类型的返回值。

也可以使用Fooas receiver 而不是*Foo. 在这种情况下,我们不必在地图中取消引用它,我们通过foo而不是&foo.

于 2021-01-06T01:45:24.353 回答