为什么我的从接口方法返回的结构体在golang中没有实现另一个接口?

huangapple go评论78阅读模式
英文:

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

问题

我有这段代码。

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)
}

它返回了一个错误:

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

但是我的 *balance 正确实现了 Monetary 接口。这段代码不会有任何错误:

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

得到了错误,但期望没有任何错误。

英文:

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

答案1

得分: 1

正如mkopriva在评论中所说:

实现接口时,方法的签名必须完全匹配,即方法的名称必须相同,输入参数类型和输出参数类型必须完全相同。

在类型方面要非常严格。即使*balance实现了Monetary接口,func (*account) GetBalance() *balance仍然不满足GetBalance() Monetary

修复方法很简单。只需将accountGetBalance方法的返回类型从*balance改为Monetary

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

由于*balance实现了Monetary接口,account.GetBalance可以将a.b作为Monetary接口返回,其中a.b是一个持有*balance的指针。

英文:

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.

huangapple
  • 本文由 发表于 2023年3月25日 19:01:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75841238.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定