Mixins 可以使用嵌入在 Go (1.4.1) 中实现,并且由于不struct{}占用内存(据我所知)它适合我们想要添加一些功能或只是向一个实际上无关的类型添加方法的情况与它的状态,但我们喜欢避免ParseThing(...),而是写thing.Parse(...).
所以有:
type X struct{}
func (x X) F() {
fmt.Println("functionality in X.F()")
}
type Y struct{ X }
type Z struct{ Y }
那么如果我们这样做:
var z Z
z.F()
会给我们:
functionality in X.F()
到现在为止还挺好。
现在让我们OX使用方法添加另一种类型F()并将其嵌入Z:
type Z struct {
Y
OX
}
type OX struct{} // overriding X
func (x OX) F() {
fmt.Println("functionality in OX.F()")
}
有趣的!现在我们得到了functionality in OX.F(),它向我们展示了 Go 编译器搜索该方法,从 type it self 开始,然后是最后一个嵌入类型。我们可以通过添加F()到Z:
func (x Z) F() {
fmt.Println("functionality in Z.F()")
}
输出是functionality in Z.F()。现在,如果我们删除该Z.F()方法并添加F()到Y:
//func (x Z) F() {
// fmt.Println("functionality in Z.F()")
//}
func (x Y) F() {
fmt.Println("functionality in Y.F()")
}
然后我们看到这个错误ambiguous selector z.F;通过指针重定向没有区别。
问题1:为什么会这样?
额外的间接级别Y意味着其他东西,但让我想到了这一点。正如我所猜测的那样,这func (t T) String() string{}是一个例外。这段代码:
type X struct{}
func (x X) String() string {
return "in X.String()"
}
type Y struct{ X }
type Z struct {
Y
OX
}
type OX struct{} // overriding X
func (x OX) String() string {
return "in OX.String()"
}
func (x Y) String() string {
return "in Y.String()"
}
然后这个:
var z Z
fmt.Println(z)
给我们:
{in Y.String() in OX.String()}
这是合乎逻辑的。但是如果我们使用指针接收器:
import (
"fmt"
"testing"
)
func TestIt(t *testing.T) {
var z Z
fmt.Println(z)
}
type X struct{}
func (x *X) String() string {
return "in X.String()"
}
type Y struct{ X }
type Z struct {
Y
OX
}
type OX struct{} // overriding X
func (x *OX) String() string {
return "in OX.String()"
}
func (x *Y) String() string {
return "in Y.String()"
}
会打印出来:
{{{}} {}}
问题2:为什么会这样?
GCT1015
SMILET
相关分类