golang公共方法到私有结构 - 这有任何用例

时间:2016-06-21 18:50:16

标签: go encapsulation

我是新手。我注意到在一些库中有私有结构的公共方法。请参阅示例https://github.com/btcsuite/btcd/blob/master/txscript/stack.go

这是否有真实的用例。如果我无法访问他们所属的结构,我无法想象我将如何使用公共方法。

如下面的问题 - 是否有任何方法可以克服结构的私有声明。例如,我想使用我的包中指向文件的结构堆栈。

2 个答案:

答案 0 :(得分:12)

因此,对此的主要用例是您可以从包函数返回未导出的类型。然后可以在此类型上使用任何导出的方法,即使其他包实际上不能在第一个位置实际创建该类型(除非将其作为包中的返回值接收)。

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

然后定义一些实现该接口的私有类型:

type stringDoer struct {}

func (s *stringDoer) Do() {}

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

这样外部包可以使用我的类型作为接口而不必乱用具体类型,并且因为我的包的公开数据类型完全是接口,所以它会对我的包进行模拟或存根调用(例如,用于测试)非常容易。

要使这种类型的系统起作用,必须导出struct上的方法(在本例中为stringDoer),即使结构本身不是。

答案 1 :(得分:1)

这是取消导出它的提交:https://github.com/btcsuite/btcd/commit/7411e65b1e8d4e4c6da198590ad627bfe253173c。来自提交消息:

  

此提交取消导出Stack类型,因为它只是用于   在脚本执行期间内部使用。此外,发动机暴露   返回项目的{G,S} etStack和{G,S} etAltStack函数   作为一个字节片([] [] byte)的片段,用于在步进时调用者访问。

我相信你(在包之外)不能使用这个结构是正确的。它纯粹在包实现中使用。