我有几种方法可以调用某些情况(例如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中创建方法地图?
答案 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()
以字符串形式返回操作,例如来自用户输入。
a
和 b
是方法的 string 和 int 参数。
这假设所有方法都具有相同的签名。它们也可以有返回值,同样是相同的类型。
也可以用 Foo
作为接收者而不是 *Foo
来做到这一点。在这种情况下,我们不必在地图中取消引用它,而是传递 foo
而不是 &foo
。