我是新手。我注意到在一些库中有私有结构的公共方法。请参阅示例https://github.com/btcsuite/btcd/blob/master/txscript/stack.go
这是否有真实的用例。如果我无法访问他们所属的结构,我无法想象我将如何使用公共方法。
如下面的问题 - 是否有任何方法可以克服结构的私有声明。例如,我想使用我的包中指向文件的结构堆栈。
答案 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)的片段,用于在步进时调用者访问。
我相信你(在包之外)不能使用这个结构是正确的。它纯粹在包实现中使用。