3 回答
TA贡献1803条经验 获得超6个赞
GetStructName
Parent
是not类型的方法Child
,而且 Golang 没有继承,而是有结构嵌入(也有接口嵌入),这有点像继承,但有一个关键的区别:
当我们嵌入一个类型时,该类型的方法成为外部类型的方法,但是当它们被调用时,方法的接收者是内部类型,而不是外部类型。
这基本上意味着当您调用时GetStructName
,方法的接收者是Parent
(内部或嵌入类型),而不是Child
。
这与典型的类继承根本不同,它解释了您所看到的行为。
TA贡献1843条经验 获得超7个赞
为了完整起见,我想分享我的解决方案
package main
import (
"fmt"
"log"
"reflect"
)
// we need an interface so methods are being embedded automatically
type IParent interface {
Init(IParent) IParent
}
// internal private fields, non-visible from the outside
type Parent struct {
_IsInitialized bool
_Self IParent
}
// init the struct, set "_Self" to it's caller
func (p *Parent) Init(o IParent) IParent {
p._Self = o
p._IsInitialized = true
return o
}
// This method uses "_Self" to determine what it actually is
func (p *Parent) GetStructName() string {
if !p._IsInitialized {
log.Fatal("Struct not initialized. You may call 'myVar.Init(&myVar)' to initialize it.")
}
return reflect.TypeOf(p._Self).Elem().Name()
}
// Below childs have "Init()" from Parent, so they implement IParent automatically
// No need to duplicate any methods here anymore
type Child1 struct {
Parent
}
type Child2 struct {
Parent
}
type Child3 struct {
Parent
}
type Child4 struct {
Parent
}
func main() {
myChild1 := Child1{}
myChild1.Init(&myChild1) // Init object (set _Self on struct)
fmt.Println(myChild1.GetStructName()) // Gives "Child1"
myChild2 := Child2{}
myChild2.Init(&myChild2) // Init object (set _Self on struct)
fmt.Println(myChild2.GetStructName()) // Gives "Child2"
myChild3 := Child3{}
myChild3.Init(&myChild3) // Init object (set _Self on struct)
fmt.Println(myChild3.GetStructName()) // Gives "Child3"
myChild4 := Child4{}
fmt.Println(myChild4.GetStructName()) // Fatal error
}
// Footnotes:
//---
//
// This attempt tries to solve a go 'inheritance' problem although go is *NOT* meant to be an OOP language. It was a funny experiment still :-)
// License: open domain, no attribution
// https://www.xsigndll.com
//
//---
TA贡献1921条经验 获得超9个赞
你可以“排序”通过(有点难看)获得你可能正在寻找的行为:
package main
import (
"fmt"
"reflect"
)
type NamedReturningType interface {
GetStructName() string
}
type Parent struct {
Id uint32
}
func (p *Parent) GetStructName() string {
return reflect.TypeOf(p).Elem().Name()
}
type Child struct {
Parent
}
func (c *Child) GetStructName() string {
return reflect.TypeOf(c).Elem().Name()
}
func main() {
myChild := Child{}
fmt.Println(myChild.GetStructName())
myParent := Parent{}
fmt.Println(myParent.GetStructName())
}
(游乐场:https://play.golang.org/p/qEtoEulFSPy)
编辑:添加了这些类型可以实现的接口,以使代码更通用。
- 3 回答
- 0 关注
- 156 浏览
添加回答
举报