如何将go方法转换为func?

时间:2012-03-31 18:24:22

标签: go

我有一个包级函数(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。

3 个答案:

答案 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)

从Go 1.1开始,C#风格的方法参考有效:

Frob( myFrob.FrobMethod )

请参阅Go语言规范的Method expressions部分。