Go 用变量参数实现接口方法

Go 用变量参数实现接口方法,go,interface,Go,Interface,我从简单的界面开始: type Module interface { Init(deps ...interface{}) error } 我认为,实现将非常简单,因为这个方法应该匹配任何数量的参数。这就是我用这段代码得出的结论,我想,TestModule实现了Module接口 type TestModule struct { } func (m *TestModule) Init(str string) error { return nil } 但是,当我想将TestMod

我从简单的界面开始:

type Module interface {
    Init(deps ...interface{}) error
}
我认为,实现将非常简单,因为这个方法应该匹配任何数量的参数。这就是我用这段代码得出的结论,我想,
TestModule
实现了
Module
接口

type TestModule struct {
}

func (m *TestModule) Init(str string) error {
    return nil
}
但是,当我想将TestModule传递给任何需要该模块的函数时,我会得到以下错误:

无法将模块(类型*TestModule)用作testFunc的参数中的类型模块:


编辑:是否有实现这种行为的最佳实践?

这不实现接口

func (m *TestModule) Init(str string) error {
    return nil
}
出现混淆的地方是“因为此方法应匹配任意数量的提供参数”,这是一种语言特性,允许调用方使用可变数量的参数调用此方法(请参见此处)。要实现它,您需要实现相同的签名含义
。。。接口{}

因此,需要明确的是,“任意数量的提供参数”仅用于调用该方法,这并不意味着您可以使用任何类型的任何参数集实现该方法,并且它将具有相同的定义。该定义说明调用方传入的实现
接口{}
的项的数量是可变的

“是否有实施此类行为的最佳实践?”

据我所知没有。我认为通常的做法是放松传递到
接口{}
的类型。。。接口{}
,然后检查方法内部的集合。例如,如果
模块
接口将其定义为
Init(deps接口{})error
,那么您可以像这样在测试模块中实现它

func (m *TestModule) Init(deps interface{}) error {
      str := deps.(string)
      return nil
}

如果希望参数长度可变,只需在方法中添加一个
for range
构造,以取消对值的装箱或执行一些边界检查。我不能说这在您的应用程序中是否是一个好的实践,因为我认为这取决于您从单一方法sig中获得的价值。它添加了额外的锅炉板代码,并有一些轻微的性能损失。

这没有实现接口

func (m *TestModule) Init(str string) error {
    return nil
}
出现混淆的地方是“因为此方法应匹配任意数量的提供参数”,这是一种语言特性,允许调用方使用可变数量的参数调用此方法(请参见此处)。要实现它,您需要实现相同的签名含义
。。。接口{}

因此,需要明确的是,“任意数量的提供参数”仅用于调用该方法,这并不意味着您可以使用任何类型的任何参数集实现该方法,并且它将具有相同的定义。该定义说明调用方传入的实现
接口{}
的项的数量是可变的

“是否有实施此类行为的最佳实践?”

据我所知没有。我认为通常的做法是放松传递到
接口{}
的类型。。。接口{}
,然后检查方法内部的集合。例如,如果
模块
接口将其定义为
Init(deps接口{})error
,那么您可以像这样在测试模块中实现它

func (m *TestModule) Init(deps interface{}) error {
      str := deps.(string)
      return nil
}

如果希望参数长度可变,只需在方法中添加一个
for range
构造,以取消对值的装箱或执行一些边界检查。我不能说这在您的应用程序中是否是一个好的实践,因为我认为这取决于您从单一方法sig中获得的价值。它增加了额外的锅炉板代码,并有一些轻微的性能损失。

@Gelidus在这方面我帮不了大忙,但我给了你我的两分钱。@Gelidus我帮不了大忙,但我给了你我的两分钱。