为了账号安全,请及时绑定邮箱和手机立即绑定

获取外部/父结构名称

获取外部/父结构名称

Go
Cats萌萌 2023-06-01 17:16:18
我面临一个 Golang 初学者问题,我不知道如何正确解决它。请你帮助我好吗?信息:尽管这违背了 Go 的概念(不是试图成为一种 OOP 语言),但我仍然想讨论一些解决方案。我想知道接收器/子项中的外部/父结构名称。请查看以下代码(游乐场:https ://play.golang.org/p/h6dARJQwidS )package mainimport (    "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),但我认为这不是一个好的解决方案。
查看完整描述

3 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

GetStructNameParent是not类型的方法Child,而且 Golang 没有继承,而是有结构嵌入(也有接口嵌入),这有点像继承,但有一个关键的区别:

当我们嵌入一个类型时,该类型的方法成为外部类型的方法,但是当它们被调用时,方法的接收者是内部类型,而不是外部类型。

这基本上意味着当您调用时GetStructName,方法的接收者是Parent(内部或嵌入类型),而不是Child

这与典型的类继承根本不同,它解释了您所看到的行为。


查看完整回答
反对 回复 2023-06-01
?
蓝山帝景

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

//

//---


查看完整回答
反对 回复 2023-06-01
?
郎朗坤

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


编辑:添加了这些类型可以实现的接口,以使代码更通用。


查看完整回答
反对 回复 2023-06-01
  • 3 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信