3 回答

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個贊
GetStructName
Parent
是not類型的方法Child
,而且 Golang 沒有繼承,而是有結(jié)構(gòu)嵌入(也有接口嵌入),這有點(diǎn)像繼承,但有一個關(guān)鍵的區(qū)別:
當(dāng)我們嵌入一個類型時,該類型的方法成為外部類型的方法,但是當(dāng)它們被調(diào)用時,方法的接收者是內(nèi)部類型,而不是外部類型。
這基本上意味著當(dāng)您調(diào)用時GetStructName
,方法的接收者是Parent
(內(nèi)部或嵌入類型),而不是Child
。
這與典型的類繼承根本不同,它解釋了您所看到的行為。

TA貢獻(xiàn)1843條經(jīng)驗(yàn) 獲得超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貢獻(xiàn)1921條經(jīng)驗(yàn) 獲得超9個贊
你可以“排序”通過(有點(diǎn)難看)獲得你可能正在尋找的行為:
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)
編輯:添加了這些類型可以實(shí)現(xiàn)的接口,以使代碼更通用。
- 3 回答
- 0 關(guān)注
- 215 瀏覽
添加回答
舉報(bào)