2012-03-31 98 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