具体示例如下:https://play.golang.org/p/ZNmviKWLwe
我有一个接口A.我希望A的所有实现都有一定的签名(因此接口)。我希望其中一个返回实现另一个接口的有用的东西。
type Box interface {
GetToy(int) (*Toy, error)
}
type Toy interface{
Play()
}
type CarBox struct {
Length int
Width int
Height int
toys []*Matchbox
}
type Matchbox struct {}
func (b *CarBox) Size () int {
return b.Length*b.Width*b.Height
}
func (b *CarBox) GetToy(j int) (*Matchbox, error) {
return b.toys[j], nil
}
func (m *Matchbox) Play() {
fmt.Println("Zoom!")
}
但当然,它不起作用,因为GetToy()
返回*Matchbox
而不是*Toy
,即使Matchbox
是Toy
完全可以接受的实现1}}。而且,不,它不是因为指针;无论我在*Toy
中返回GetToy
还是仅在Toy
返回{<1}},都会得到相同的结果:
tmp/sandbox721971102/main.go:33:15: cannot use CarBox literal (type CarBox) as type Box in return argument:
CarBox does not implement Box (wrong type for GetToy method)
have GetToy(int) (*Matchbox, error)
want GetToy(int) (*Toy, error)
显然,我的模式并不匹配如何运作。什么是&#34;正确&#34;这样做的方法?
答案 0 :(得分:4)
首先,您几乎不需要指向接口类型的指针。因此,GetToy
方法签名应更改为:
type Box interface {
GetToy(int) (Toy, error) // use Toy, not *Toy
}
现在,请注意隐式地按类型满足接口。因此,通过实现Play()
方法,*Matchbox
隐式满足Toy
接口(请注意*
,实现Toy
接口的类型为指向Matchbox
和而非Matchbox
的指针。
这意味着类型*Matchbox
的值可以替换为类型Toy
。那么剩下的就是修复GetToy
上定义的*CarBox
方法:
func (b *CarBox) GetToy(j int) (Toy, error) {
return b.toys[j], nil
}
现在上面GetToy
将返回*Matchbox
,它确实实现了Toy
界面。
答案 1 :(得分:1)
一些修正:https://play.golang.org/p/-mDr5SDZvV
指向界面的指针是非常需要的东西。使用界面 - 它可以包含具体类型。
<强>更新强>:
如果你希望有一个像func (b *CarBox) GetToy(j int)
这样的指针接收器的方法,你可以从Tester
函数返回指针(注意&amp; ):
func Tester() Box {
return &CarBox{}
}
这样,从Tester返回的接口值将结束指向CarBox
实例的指针。因此Go运行时将能够使用指针接收器运行方法。否则只有一个值而不是一个指针。因此,只能调用带有值接收器的方法。