我有一个包,其中未导出结构并导出了用于创建它的新函数以及在此结构上运行的导出函数(例如此处建议的: Return an unexported type from a function )。 如果我在调用 New 的同一位置运行该函数,我可以运行包函数,但无法将此实体发送到另一个函数。 无需将所有代码放在一个函数中即可实现此行为的最佳方法是什么
例如,这个有效:
client := package.New()
client.Foo()
但这行不通:
client := package.New()
hello(client)
func hello(client interface{}) {
client.Foo()
}
最佳答案
您的 hello
函数本质上需要的是具有 Foo
函数的东西。这就是 go 有接口(interface)的原因。返回未导出的类型没有任何问题(事实上,这很常见,而且通常是正确的做法)。我要做的是这样的:
package foobar
// whatever thing that has a Foo function
type FClient interface {
Foo()
}
func Hello(client FClient) {
client.Foo() // will work
}
这样做的原因是为了能够对这段代码进行单元测试:
package foobar_test
import (
"testing"
)
type testFC struct {
callCount uint64
}
// implement interface
func (t testFC) Foo() {
testFC.callCount++
}
func TestHello(t *testing.T) {
client := testFC{}
Hello(client)
if client.callCount != 1 {
t.Fail("dependency not called")
}
}
当然,对于更复杂的依赖关系,您可以使用诸如mockgen之类的工具或类似的东西,但您明白了。根据定义,UNIT 测试侧重于单个代码单元。测试包单元所需要做的最后一件事是实例化另一个包中的类型。您应该能够模拟代码所依赖的所有内容。最好的方法是接口(interface)。
关于go - 如何使用未导出结构体的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58268837/