msimsp
我想得到"我是Sub"但是我得到了#34;我超级"代替。
我已经知道sub.WhoAmI将调用sub.Super.WhoAmI,但我仍然想知道是否有办法获得"我是Sub"。在Python中,当我编写以下代码时:
package main
import "fmt"
type Super struct{}
func (super *Super) name() string {
return "Super"
}
func (super *Super) WhoAmI() {
fmt.Printf("I'm %s.\n", super.name())
}
type Sub struct {
Super
}
func (sub *Sub) name() string {
return "Sub"
}
func main() {
sub := &Sub{Super{}}
sub.WhoAmI()
}
我可以得到"我是Sub"。
答案 0 :(得分:7)
嵌入不是子类化。 Go中没有超类或子类。 Sub
这里不是Super
的“孩子”。它包含Super
。你无法做到。您需要以不同的方式组织代码,以便不需要它。
例如,这里(playground)是一种更自然的方式在Go中执行此操作:
package main
import "fmt"
type Namer interface {
Name() string
}
type Super struct{}
func (sub *Super) Name() string {
return "Super"
}
type Sub struct{}
func (sub *Sub) Name() string {
return "Sub"
}
func WhoAmI(namer Namer) {
fmt.Printf("I'm %s.\n", namer.Name())
}
func main() {
sub := &Sub{}
WhoAmI(sub)
}
不是专注于类(Go没有),而是专注于接口。这不是是什么的问题,而是他们可以做什么的问题。这是一种非常强大的编程方法,在实践中通常比继承抽象更灵活,更不容易出错。
答案 1 :(得分:2)
将Go中的函数想象为它们都属于单个命名空间。 Go真的没有类,方法或继承,所以你尝试的东西永远不会按你想要的方式工作。
换句话说,当你定义一个这样的函数时:
func (f *Foo) DoStuff()
你可以想象真的被定义为:
func DoStuff(f *Foo)
所以你可能会注意到为什么Go选择在name
结构上调用Super
函数 - 它是唯一匹配的函数签名。 (请注意,在WhoAmI
函数super
中定义为super *Super
,因此Go会将其与相同类型的相应函数进行匹配。)
至于如何以Go方式执行此操作,请尝试使用接口:
<强> http://play.golang.org/p/8ELw-9e7Re 强>
package main
import "fmt"
type Indentifier interface {
WhoAmI() string
}
type A struct{}
func (a *A) WhoAmI() string {
return "A"
}
type B struct{}
func (b *B) WhoAmI() string {
return "B"
}
func doSomething(x Indentifier) {
fmt.Println("x is a", x.WhoAmI())
}
func main() {
doSomething(&A{})
doSomething(&B{})
}