Go中的方法地图

时间:2013-02-26 13:13:40

标签: methods go

我有几种方法可以调用某些情况(例如Add,Delete等)。然而,随着时间的推移,案件的数量正在增加,我的开关箱也越来越长。所以我想我会创建一个方法地图,比如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 个答案:

答案 0 :(得分:9)

是。目前:

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

稍后:请参阅guelfi提到的go11func文档。

答案 1 :(得分: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))
}

此值可以像其他任何内容一样存储在地图中。

答案 2 :(得分:0)

您可以使用方法表达式来做到这一点:

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

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

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

类似地,您可以使用func(*Foo, string, int)获得签名为(*Foo).Add的函数

答案 3 :(得分: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)

其中 GetOp() 以字符串形式返回操作,例如来自用户输入。 ab 是方法的 string 和 int 参数。

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

也可以用 Foo 作为接收者而不是 *Foo 来做到这一点。在这种情况下,我们不必在地图中取消引用它,而是传递 foo 而不是 &foo