2016-06-21 35 views
1

我是新來的。我注意到在一些庫中有一個私有結構的公共方法。看例如https://github.com/btcsuite/btcd/blob/master/txscript/stack.gogolang public method to private struct - 這是否有任何用例

這是否有一個真正的用例。我無法想象如果我無法訪問它們所屬的結構,我將如何使用公共方法。

由於以下問題 - 是否有任何方法來克服結構的私有聲明。例如,我想使用包中指向文件的結構堆棧。

回答

7

所以,主要的用例是你可以從包函數中返回一個未導出的類型。任何導出的方法都可以用於這種類型,即使其他包不能實際創建類型(除了將其作爲包的返回值接收)。

package foobar 

type foo struct {} 
func (f foo) Bar() {} 
func Newfoo() foo { 
    return foo{} 
} 
---- 
package main 
func main() { 
    f := foobar.Newfoo() 
    f.Bar() 

    foobar.NewFoo().Bar() 
} 

另一個主要用例是封裝級接口。我傾向於其中一個包定義導出的接口,像這樣使用一個相當標準模式:

type Doer interface { 
    Do() 
} 

,然後定義一些私人型(s)表示,滿足該接口:

type stringDoer struct {} 

func (s *stringDoer) Do() {} 

func NewStringDoer() Doer { 
    return &stringDoer{} 
} 

這樣外部包可以使用我的類型作爲接口,而不必混淆具體類型,而且由於我的包的公開數據類型完全是接口,因此它使我的包(例如測試)的模擬或存根呼叫非常容易。

要使這種類型的系統工作,必須導出結構上的方法(在本例中爲stringDoer),即使結構本身不是。

1

這是未提交它的提交:https://github.com/btcsuite/btcd/commit/7411e65b1e8d4e4c6da198590ad627bfe253173c。從提交消息:

此提交取消導出堆疊型,因爲它僅是爲了進行腳本執行期間內部使用 。此外,引擎公開了{G,S} etStack和{G,S} etAltStack函數,這些函數返回 作爲一個字節切片片段([] []字節),用於呼叫者在步進時訪問。

我相信你是正確的,你(外包)不能使用這個結構。它完全在包實現中使用。

+0

Go在Go返回公共接口的私有實現方面非常普遍。該模式在整個stdlib中使用。 – JimB

相關問題