我很好奇Go中是否有可能。我有多种方法的类型。是否可以有一个函数,该函数需要一个方法参数,然后将其称为类型?
这是我想要的一个小例子:
package main import ( "fmt" ) type Foo int func (f Foo) A() { fmt.Println("A") } func (f Foo) B() { fmt.Println("B") } func (f Foo) C() { fmt.Println("C") } func main() { var f Foo bar := func(foo func()) { f.foo() } bar(A) bar(B) bar(C) }
Go认为type Foo有一个称为的方法foo(),而不是用传入的方法名称替换它。
Foo
foo()
是的,有可能。您有2(3)个选项:
该表达式Foo.A产生的功能A与第一个参数等效,但具有一个显式接收器。它有签名func(f Foo)。
Foo.A
A
func(f Foo)
var f Foo bar := func(m func(f Foo)) { m(f) } bar(Foo.A) bar(Foo.B) bar(Foo.C)
在这里,方法接收器是显式的。您只需将方法名称(具有它所属的类型)传递给bar(),并且在调用它时,您必须传递实际的接收者:m(f)。
bar()
m(f)
预期的输出(在Go Playground上尝试):
A B C
如果f是type的值Foo,则表达式会f.A产生func()具有隐式接收者值的type的函数值f。
f
f.A
func()
var f Foo bar := func(m func()) { m() } bar(f.A) bar(f.B) bar(f.C)
请注意,这里的方法接收器是隐含的,它被保存与传递给函数的值bar(),所以它被称为没有明确指定它:m()。
m()
输出是相同的(在Go Playground上尝试)。
不如以前的解决方案(在性能和“安全性”上都不错),但是您可以将方法的名称作为string值传递,然后使用该reflect包使用该名称来调用方法。它可能看起来像这样:
string
reflect
var f Foo bar := func(name string) { reflect.ValueOf(f).MethodByName(name).Call(nil) } bar("A") bar("B") bar("C")
在Go Playground上尝试一下。