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 關注
- 202 瀏覽
添加回答
舉報