猿问

获取外部/父结构名称

我面临一个 Golang 初学者问题,我不知道如何正确解决它。请你帮助我好吗?

信息:尽管这违背了 Go 的概念(不是试图成为一种 OOP 语言),但我仍然想讨论一些解决方案。

我想知道接收器/子项中的外部/父结构名称。请查看以下代码(游乐场:https ://play.golang.org/p/h6dARJQwidS )

package main


import (

    "fmt"

    "reflect"

)


type Parent struct {

    Id uint32

}


func (p *Parent) GetStructName() string {

    return reflect.TypeOf(p).Elem().Name()

}



type Child struct {

    Parent

}



func main() {

    myChild := Child{}

    fmt.Println(myChild.GetStructName()) // Gives "Parent" instead of "Child". How to get "Child"?

}

它显示“父”,尽管结构是“子”。谁能告诉我如何获得正确的结构名称?我在另一个 stackoverflow 主题中看到一个“解决方案”“正确”工作(Go - get parent struct),但我认为这不是一个好的解决方案。



Cats萌萌
浏览 157回答 3
3回答

慕码人8056858

GetStructNameParent是not类型的方法Child,而且 Golang 没有继承,而是有结构嵌入(也有接口嵌入),这有点像继承,但有一个关键的区别:当我们嵌入一个类型时,该类型的方法成为外部类型的方法,但是当它们被调用时,方法的接收者是内部类型,而不是外部类型。这基本上意味着当您调用时GetStructName,方法的接收者是Parent(内部或嵌入类型),而不是Child。这与典型的类继承根本不同,它解释了您所看到的行为。

蓝山帝景

为了完整起见,我想分享我的解决方案package mainimport (    "fmt"    "log"    "reflect")// we need an interface so methods are being embedded automaticallytype IParent interface {    Init(IParent)   IParent}// internal private fields, non-visible from the outsidetype Parent struct {    _IsInitialized  bool    _Self           IParent}// init the struct, set "_Self" to it's callerfunc (p *Parent) Init(o IParent) IParent {    p._Self = o    p._IsInitialized = true    return o}// This method uses "_Self" to determine what it actually isfunc (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 anymoretype 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////---

郎朗坤

你可以“排序”通过(有点难看)获得你可能正在寻找的行为:package mainimport (    "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)编辑:添加了这些类型可以实现的接口,以使代码更通用。
随时随地看视频慕课网APP

相关分类

Go
我要回答