【问题标题】:How should I declare an interface that has a method to return a slice of a different interface?我应该如何声明一个具有返回不同接口切片的方法的接口?
【发布时间】:2026-01-05 07:45:01
【问题描述】:

这是我创建的一个示例,我在其中声明了我的第一个结构,它是一个 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))
}

我的ToolboxInterface 声明了我已经实现的GetHammers() 方法。但是 CountHammersInToolbox 方法返回 1 而不是输出中的 3。

uberswe$ go run scratch/main.go 
3
1

我尝试了不同的变体,但我觉得有点卡住了。我不明白为什么它返回 1 但我怀疑我以错误的方式声明我的接口方法。

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

【问题讨论】:

  • 我想我通过将Toolbox 结构更改为Hammers []HammerInterface 解决了这个问题,但我不确定为什么要这样声明。我对可以很好地解释这一点或链接到好的指南/文档的答案感兴趣。

标签: go


【解决方案1】:

您的接口定义没有任何问题。问题是您没有正确地将[]Hammer 转换为[]HammerInterface。看起来您希望这会神奇地发生,但事实并非如此。

在这段代码中:

func (t Toolbox) GetHammers() []HammerInterface  {
    return []HammerInterface{t.Hammers}
}

您可能期望返回的结果是 3 个HammerInterfaces 的切片,但实际上您得到的是单个HammerInterface,它实际上是三个Hammerss 的切片。

您必须手动进行此转换。详情请见this post

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 接口,但在您的情况下,由于该接口为空,它匹配任何类型,就像interface{} 一样。

【讨论】:

    最近更新 更多