我的应用程序中有一个单例,但它不是直接作为结构发布,而是作为接口发布(因为我希望能够在初始化单例时动态选择特定的实现)。这是代码:
var once sync.Once
var instance defaultConfiguration
type Configuration interface {
GetFoo() string
}
type defaultConfiguration struct {
}
func (dc defaultConfiguration) GetFoo() string {
return "foo"
}
func NewConfiguration() Configuration {
once.Do(func() {
instance = defaultConfiguration{}
})
return instance
}
然后,我决定编写一个单元测试,以检查NewConfiguration()
每次实际上都会返回相同的实例:
func TestNewConfigurationSameInstance(t *testing.T) {
configuration1 := NewConfiguration()
configuration2 := NewConfiguration()
if &configuration1 != &configuration2 {
t.Error()
}
}
我认为比较返回的实例的地址是有意义的,但是,此测试失败。
然后我想,也许我必须返回一个指向实例的指针,所以我将代码更改为如下所示:
func NewConfiguration() *Configuration {
once.Do(func() {
instance = defaultConfiguration{}
})
return &instance
}
但是这甚至无法编译:失败,并显示错误消息
不能在返回参数中使用&instance(类型* defaultConfiguration)作为类型* Configuration:*配置是指向接口的指针,不是接口
而且我很困惑。为什么不能返回指向接口的指针?或者,为什么将defaultConfiguration
返回为Configuration
是有效的,但是将*defaultConfiguration
返回为*Configuration
却无效?
毕竟,对于我的用例而言,正确的单元测试是什么?
var once sync.Once
var instance *defaultConfiguration
type Configuration interface {
GetFoo() string
}
type defaultConfiguration struct {
}
func (dc *defaultConfiguration) GetFoo() string {
return "foo"
}
func NewConfiguration() Configuration {
once.Do(func() {
instance = &defaultConfiguration{}
})
return instance
}
因为Configuration
是一个接口,并且您想要一个指向defaultConfiguration
的指针来实现它。