【问题标题】:Interface conversion with different return values implementing the same interface不同返回值实现同一个接口的接口转换
【发布时间】:2016-06-07 04:04:58
【问题描述】:

Go 新手。我正在尝试编写一个涉及模拟几个结构的测试,其中一个结构的函数返回另一个结构的实例。但是我遇到了一个可以使用以下代码重现的问题:

package main

type Machine1 interface {
    Produce() Material1
}

type Machine2 interface {
    Produce() Material2
}

type Material1 interface {
    Use() error
}

type Material2 interface {
    Use() error
}

type PencilMachine struct{}

func (pm *PencilMachine) Produce() Material1 {
    return &Pencil{}
}

type Pencil struct{}

func (p *Pencil) Use() error {
    return nil
}

func main() {
    pm := new(PencilMachine)

    var m1 Machine1
    m1 = Machine1(pm)

    var m2 Machine2
    m2 = Machine2(m1)

    _ = m2
}

这给出了以下错误:

prog.go:38: cannot convert m1 (type Machine1) to type Machine2:
    Machine1 does not implement Machine2 (wrong type for Produce method)
        have Produce() Material1
        want Produce() Material2

注意 Pencil 结构体是如何实现 Material1 和 Material2 接口的。但是 (pm *PencilMachine) Produce() 的返回类型是 Material1 而不是 Material2。很好奇为什么这不起作用,因为实现 Material1 的任何东西也实现了 Material2。

谢谢!

https://play.golang.org/p/3D2jsSLoI0

【问题讨论】:

标签: go


【解决方案1】:

将接口更多地视为合同。它们不会仅仅因为它们不直接实现任何东西而隐式实现其他接口。

接口满足于实现。 (希望这是有道理的)

在您的示例中,两种机器类型都可以创建简单的“材料”,如下所示:https://play.golang.org/p/ZoYJog2Xri

package main

type Machine1 interface {
    Produce() Material
}

type Machine2 interface {
    Produce() Material
}

type Material interface {
    Use() error
}

type PencilMachine struct{}

func (pm *PencilMachine) Produce() Material {
    return &Pencil{}
}

type Pencil struct{}

func (p *Pencil) Use() error {
    return nil
}

func main() {
    pm := new(PencilMachine)

    var m1 Machine1
    m1 = Machine1(pm)

    var m2 Machine2
    m2 = Machine2(m1)

    _ = m2
}

【讨论】:

    【解决方案2】:

    这是因为您的铅笔机没有实现 Machine2 接口。这是罪魁祸首:

    func (pm *PencilMachine) Produce() Material1 {
        return &Pencil{}
    }
    

    您会看到,尽管 PencilMachine 具有相同的函数 Produce,但它不会返回相同的数据类型 (Material1),因此它仅实现 Machine1。 Machine2 需要 Produce 函数才能返回 Material2

    【讨论】:

      猜你喜欢
      • 2016-02-03
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2023-01-28
      • 2014-01-24
      • 1970-01-01
      相关资源
      最近更新 更多