我从简单的界面开始:
type Module interface {
Init(deps ...interface{}) error
}
我想,实现将非常简单,因为此方法应匹配任意数量的提供参数。这就是我最终得到的代码,思考,TestModule
实现了Module
接口。
type TestModule struct {
}
func (m *TestModule) Init(str string) error {
return nil
}
但是当我想将TestModule传递给任何想要Module的函数时,我收到了这个错误:
不能将模块(类型* TestModule)用作testFunc参数中的类型Module:
func testFunc(module Module) {
}
编辑:有没有最佳实践来实现这种行为?
答案 0 :(得分:6)
这不实现界面;
func (m *TestModule) Init(str string) error {
return nil
}
如果您的混淆出现在“因为此方法应匹配任意数量的提供的参数”这是一种语言功能,它允许调用者使用可变数量的参数调用该方法(请参阅此处{ {3}})。要实现它,您需要实现相同的签名,意思是... interface{}
。
所以要明确的是,“任意数量的提供参数”仅用于调用方法,这并不意味着您可以使用任何类型的任何参数集来实现该方法,并且它将具有相同的定义。该定义指出,调用者传入的interface{}
实现了可变数量的项目。
“有没有最佳实践来实现这种行为?”
不是我知道的。我认为通常的做法是放宽传入interface{}
或... interface{}
的类型,然后检查方法内的集合。例如,如果Module
接口将其定义为Init(deps interface{}) error
,那么您可以像这样在测试模块中实现它;
func (m *TestModule) Init(deps interface{}) error {
str := deps.(string)
return nil
}
如果你想要可变长度的args,你只需要在方法中添加一个for range
构造来取消装箱值或进行一些边界检查。我不能说这是否适合您的应用程序,因为我认为这取决于您使用单一方法sig获得多少价值。它增加了额外的锅炉板代码,并且有一些轻微的性能损失。