2012-03-31 32 views
4

我有带一个函数作为参数的封装级函数(FROB)。对于函数参数,我想传入一个具有特定结构实例的方法(FrobMethod)作为接收者(myFrob)。如何将go方法转换为func?

我发现做到这一点的唯一方法是使用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

不是真正的时刻。有一个[开放的bug(http://code.google.com/p/go/issues/detail?id=2280)来获得类似于C# – 2012-04-03 16:04:41

+0

@PaoloFalabella东西:OK,这就是答案我一直在寻找的那种对于。谢谢。 – lnmx 2012-04-03 17:34:17

回答

0

如围棋1.1时,C#风格方法参考著作:

Frob(myFrob.FrobMethod) 

参见转到语言规范的Method expressions部分。

3

在我看来,地道的围棋应该在这种情况下使用的接口,而不是一个功能:

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) 
} 

功能HandleFuncnet/http是功能Handle的包装这需要一个接口参数。

+0

我想我们是如何发布的几乎相同的代码在精确的同一时间:-) – jdi 2012-03-31 18:56:15

+0

我只是想出了如何HandlerFunc''作品...它实际上是一个基于函数的类型是通过调用自身实现'Handler'接口。因此,从函数创建接口实现比其他方式更容易。 – lnmx 2012-03-31 20:35:44

+0

@Atom:如果我是对的,你来自golang组?你会介意在我的答案评论主题中提出分歧吗? – jdi 2012-04-03 03:11:44

1

虽然围棋确实允许你创建匿名函数赋值给变量,并通过他们周围,另一种方式来解决这个问题是使用的接口。

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。

顺便说一句,我喜欢围棋和我积极尝试用它来提高我的技能在我的工具带的工具。为了应对@Jeremy在评论,我只是指出,围棋是不是面向对象,因为它不是坚决支持围棋队是这样,其更通常被称为程序,并且,有从其他语言元素的混合物其本身被认为是OO

+0

转到开发商可能采取例外的声明,围棋是不是面向对象。事实上,他们可能会倾向于说Go不仅是OO,而且事实上更好的OO。 – 2012-04-03 02:49:57

+0

@JeremyWall:我想你可能在这两点都是错的。我不认为围棋开发商将采取例外这一声明,而围棋是不是一个传统意义上的面向对象的。 – jdi 2012-04-03 02:54:45

+0

我很确定他们会。 Go绝对是OO。说传统意义上的面向对象并不是说它不是面向对象。 – 2012-04-03 02:58:50

相关问题