Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface conversion with different return values implementing the same interface

Tags:

go

new to Go. I'm trying to write a test that involves mocking a couple of structs where one of the struct's functions returns an instance of the other struct. However I'm running into an issue that I can reproduce with the following code:

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
}

Which gives the following error:

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

Notice how the Pencil struct implements both the Material1 and Material2 interfaces. However the return type of (pm *PencilMachine) Produce() is Material1 and not Material2. Curious why this doesn't work because anything that implements Material1 also implements Material2.

Thanks!

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

like image 267
Nosajool Avatar asked Nov 27 '25 08:11

Nosajool


1 Answers

Think of interfaces more as contracts. They don't implicitly implement other interfaces simply due to the fact they don't implement anything directly.

and interfaces are satisfied by implementations. (hopefully that makes sense)

In your example, having simple "Material" that both meachine types create would work, as in this: 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
}
like image 131
David Budworth Avatar answered Dec 01 '25 18:12

David Budworth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!