我是新来的。 我注意到在某些库中,私有结构有公共方法。 参见例如https://github.com/btcsuite/btcd/blob/master/txscript/stack.go
这有真实的用例吗? 如果我也无法访问它们所属的结构,那么我将无法想象如何使用公共方法。
作为以下问题-有什么方法可以克服结构的私有声明? 例如,我想使用包中指向文件的结构堆栈。
因此,主要的用例是您可以从包函数中返回未导出的类型。然后,即使其他包实际上不能首先创建该类型,也可以在此类型上使用任何导出的方法(除了从您的包中将其作为返回值接收之外)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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() } |
另一个主要用例是在包级接口中。我倾向于使用相当标准的模式,其中一个包定义了一个导出的接口,如下所示:
1 2 3 | type Doer interface { Do() } |
然后定义一些实现该接口的私有类型:
1 2 3 4 5 6 7 | type stringDoer struct {} func (s *stringDoer) Do() {} func NewStringDoer() Doer { return &stringDoer{} } |
这样,外部包就可以将我的类型用作接口,而不必弄乱具体的类型,并且由于包的公开数据类型完全是接口,因此使对我的包的模拟或存根调用(例如,用于测试)变得异常简单。
为了使这种类型的系统正常工作,必须导出结构上的方法(在本例中为
这是取消导出它的提交:https://github.com/btcsuite/btcd/commit/7411e65b1e8d4e4c6da198590ad627bfe253173c。从提交消息:
This commit unexports the Stack type since it is only intended to be
used internally during script execution. Further, the engine exposes
the {G,S}etStack and {G,S}etAltStack functions which return the items
as a slice of byte slices ([][]byte) for caller access while stepping.
我相信您是正确的,您(在包装之外)不能使用此结构。它仅在包实现中使用。
- 它在Go中很常见,它返回公共接口的私有实现。 该模式在整个stdlib中使用。