Search code examples
gostructinterfacepolymorphism

Why my struct returning from interface method not implements another interface in golang?


I have this code.

package main

import "fmt"

type Monetary interface {
    GetDecimals() int64
}

type Account interface {
    GetBalance() Monetary
}

type balance struct {
    decimals int64
}

func (b *balance) GetDecimals() int64 {
    return 0
}

type account struct {
    b *balance
}

func (a *account) GetBalance() *balance {
    return a.b
}

func NewAccount() *account {
    return &account{
        b: &balance{},
    }
}

func main() {
    var acc Account = NewAccount()
    fmt.Println(acc)
}

Which returns me an error:

cannot use NewAccount() (value of type *account) as Account value in variable declaration: *account does not implement Account (wrong type for method GetBalance)
        have GetBalance() *balance
        want GetBalance() Monetary

But my *balance implement Monetary exactly. This code will no have any error:

func main() {
    acc := NewAccount()
    b := acc.GetBalance()
    m := (Monetary)(b)
    fmt.Println(acc, m)
}

Got error, but excepting no any error


Solution

  • As mkopriva said in a comment.

    to implement an interface the method's signature MUST match verbatim, i.e. its name MUST be the same, and its input parameter types and output parameter types MUST be identical.

    Go very strict with typing. Even though *balance implements Monetary, func (*account) GetBalance() *balance still doesn't satisfy GetBalance() Monetary.

    The fix is simple. Just change account's GetBalance to return Monetary not *balance.

    func (a *account) GetBalance() Monetary {
       ...
    

    Since since *balance implements Monetary, account.GetBalance can return an a.b as a Monetary interface holding *balance.