英文:
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。
修复方法很简单。只需将account的GetBalance方法的返回类型从*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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论