这是我创建的一个示例,在该示例中声明我的第一个结构是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))
}
我的ToolboxInterface
声明了我已经实现的GetHammers()
方法。但是,CountHammersInToolbox方法返回1而不是输出中显示的3。
uberswe$ go run scratch/main.go
3
1
我尝试了这种变化,但感觉有点卡住。我不明白为什么它返回1,但是我怀疑我以错误的方式声明了接口方法。
我应该如何声明一个接口,该接口具有一种返回不同接口的切片的方法?
答案 0 :(得分:5)
您的接口定义没有错。问题是您没有正确地将[]Hammer
转换为[]HammerInterface
。您似乎希望这会神奇地发生,但事实并非如此。
在这段代码中:
func (t Toolbox) GetHammers() []HammerInterface {
return []HammerInterface{t.Hammers}
}
您可能期望返回的结果是3个HammerInterface
的切片,但实际上,您得到的是单个HammerInterface
,实际上是3个{{1}的切片} s。
您必须手动进行此转换。有关更多详细信息,请参见this post。
Hammers
在大多数现实情况下,编译器会捕获您的错误,因为您的重锤(func (t Toolbox) GetHammers() []HammerInterface {
hammerInterfaces := make([]HammerInterface, len(t.Hammers))
for i, hammer := range t.Hammers {
hammerInterfaces[i] = t.Hammers[i]
}
return hammerInterfaces
}
)不能满足t.Hammers
接口,但是在您的情况下,因为该接口为空,它与任何类型匹配,就像HammerInterface
一样。