我有一个包级函数(Frob),它将一个函数作为参数。对于函数参数,我想传递一个方法(FrobMethod),其中特定的结构实例作为接收者(myFrob)。
我发现完成此任务的唯一方法是使用捕获目标结构的func文字/闭包。这需要重复func签名和参数,这似乎太冗长了。还有更好的方法吗?
package main
import "fmt"
func Frob( frobber func( int ) ( string ) ) {
fmt.Printf( "Frob %s\n", frobber( 42 ) )
}
type MyFrob struct {
Prefix string
}
func ( m MyFrob ) FrobMethod( n int ) ( string ) {
return fmt.Sprintf( "%s %d", m.Prefix, n )
}
func main() {
myFrob := MyFrob { Prefix: "Hello" }
// C# allows something like this:
//
//Frob( myFrob.FrobMethod )
Frob( func ( n int ) ( string ) {
return myFrob.FrobMethod( n )
} )
}
......真实世界的例子是net / http中的HandleFunc。
答案 0 :(得分:4)
在我看来,在这种情况下,惯用Go应该使用接口而不是函数:
package main
import "fmt"
type Frobber interface {
FrobMethod(int) string
}
func Frob(frobber Frobber) {
fmt.Printf("Frob %s\n", frobber.FrobMethod(42))
}
type MyFrob struct {
Prefix string
}
func (m MyFrob) FrobMethod(n int) string {
return fmt.Sprintf("%s %d", m.Prefix, n)
}
func main() {
myFrob := MyFrob{Prefix: "Hello"}
Frob(myFrob)
}
HandleFunc
中的函数net/http
是函数Handle
的包装器,它接受一个接口参数。
答案 1 :(得分:1)
虽然Go确实允许您创建对变量的匿名函数赋值并传递它们,但解决此问题的另一种方法是使用接口。
package main
import "fmt"
type Frobber interface {
Frob(int) string
}
type MyFrob struct {
Prefix string
}
func (m MyFrob) Frob(n int) string {
return fmt.Sprintf("%s %d", m.Prefix, n)
}
func Frob(f Frobber) {
fmt.Printf("Frob %s\n", f.Frob(42))
}
func main() {
myFrob := MyFrob {Prefix: "Hello"}
Frob(myFrob)
}
在面向对象的语言中,你可以只传递一个方法,但Go不是OO。你必须从一开始就开始大脑,不要像在其他语言中那样尝试编写代码。我有同样的问题来自Python。
顺便说一下,我喜欢Go,并且正在积极尝试用它作为工具带中的工具来提高我的技能。为了回应@Jeremy的评论,我只是说Go不是OO,因为Go团队并没有坚定地支持它,而且它通常被称为程序性的,并且混合了其他语言的元素这些本身被认为是OO
答案 2 :(得分:0)