我应该如何声明一个接口,该接口具有返回不同接口的切片的方法?

Mar*_*amn 2 go

这是我创建的一个示例,在该示例中声明第一个Toolbox包含切片的结构Hammers。我为此创建了一个接口ToolboxHammer以便其他人可以使用我的函数而不必使用我的结构,只要他们遵循我的接口实现即可。

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,但是我怀疑我以错误的方式声明了接口方法。

我应该如何声明一个接口,该接口具有返回不同接口的切片的方法?

Fli*_*mzy 5

接口定义没有错。问题是您没有正确转换[]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{}会。