这是我创建的一个示例,在该示例中声明第一个Toolbox包含切片的结构Hammers。我为此创建了一个接口Toolbox,Hammer以便其他人可以使用我的函数而不必使用我的结构,只要他们遵循我的接口实现即可。
package main
import "fmt"
type ToolboxInterface interface {
GetHammers() []HammerInterface
}
type HammerInterface interface {
}
type Toolbox struct {
Hammers []Hammer
}
func (t Toolbox)GetHammers() []HammerInterface {
return []HammerInterface{t.Hammers}
}
type Hammer struct {
Color string
}
func CountHammersInToolbox(t ToolboxInterface) int {
hammers := t.GetHammers()
return len(hammers)
}
func main() {
toolbox := Toolbox{Hammers: []Hammer{
{Color: "Red"},
{Color: "Blue"},
{Color: "Green"}}}
fmt.Println(len(toolbox.Hammers))
fmt.Println(CountHammersInToolbox(toolbox))
}
Run Code Online (Sandbox Code Playgroud)
我ToolboxInterface声明了GetHammers()我已经实现的方法。但是,CountHammersInToolbox方法返回1而不是3,如输出所示。
uberswe$ go run scratch/main.go
3
1
Run Code Online (Sandbox Code Playgroud)
我尝试了这种变化,但感觉有点卡住。我不明白为什么它返回1,但是我怀疑我以错误的方式声明了接口方法。
我应该如何声明一个接口,该接口具有返回不同接口的切片的方法?
接口定义没有错。问题是您没有正确转换[]Hammer为[]HammerInterface。您似乎希望这会神奇地发生,但事实并非如此。
在这段代码中:
func (t Toolbox) GetHammers() []HammerInterface {
return []HammerInterface{t.Hammers}
}
Run Code Online (Sandbox Code Playgroud)
您可能期望返回的结果是3 HammerInterfaces 的切片,但是,您得到的是single HammerInterface,实际上是3 Hammerss 的切片。
您必须手动进行此转换。有关更多详细信息,请参见这篇文章。
func (t Toolbox) GetHammers() []HammerInterface {
hammerInterfaces := make([]HammerInterface, len(t.Hammers))
for i, hammer := range t.Hammers {
hammerInterfaces[i] = t.Hammers[i]
}
return hammerInterfaces
}
Run Code Online (Sandbox Code Playgroud)
在大多数现实世界的情景,你的错误会被编译器捕获,因为你的锤子片(t.Hammers)将不能满足HammerInterface界面,但在你的情况下,由于该接口是空的,它匹配任何类型的,因为interface{}会。