使用可变参数实现接口方法

时间:2015-10-13 15:41:00

标签: go interface

我从简单的界面开始:

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) {

}

编辑:有没有最佳实践来实现这种行为?

1 个答案:

答案 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获得多少价值。它增加了额外的锅炉板代码,并且有一些轻微的性能损失。

相关问题