Get outer/parent struct name












-1















I'm facing a Golang begginers problem, and I don't know how to solve it correctly. Could you please help me?



Info: Even though this is against the concept of Go (not trying to be an OOP language) I'd like to discuss some solutions still.



I'd like to know the outer/parent struct name within the receiver/child. Please have a look at the following code (playground: 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"?
}


It displays "Parent", although the struct is a "Child". Can anyone tell me how to get the correct struct name? I've seen one 'solution' in another stackoverflow topic that works 'correctly' (Go - get parent struct), but I don't think this is a good solution.










share|improve this question




















  • 6





    Go does not have inheritance. Trying to pretend it does is only going to make things difficult. Rework your solution to make use of the available methods of composition instead.

    – JimB
    Jan 20 at 15:16











  • @JimB Ok. I'll dig into it. From your perspective: Can composition solve this problem or do I need to re-think the structure completely?

    – xsigndll
    Jan 20 at 15:33






  • 1





    You’re trying to solve your problem with inheritance. I’m sure there’s alterntive ways to solve your problem (there are lots of non-OOP languages), but you’re only describing your proposed solution, rather than an actual problem statement.

    – JimB
    Jan 20 at 17:00
















-1















I'm facing a Golang begginers problem, and I don't know how to solve it correctly. Could you please help me?



Info: Even though this is against the concept of Go (not trying to be an OOP language) I'd like to discuss some solutions still.



I'd like to know the outer/parent struct name within the receiver/child. Please have a look at the following code (playground: 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"?
}


It displays "Parent", although the struct is a "Child". Can anyone tell me how to get the correct struct name? I've seen one 'solution' in another stackoverflow topic that works 'correctly' (Go - get parent struct), but I don't think this is a good solution.










share|improve this question




















  • 6





    Go does not have inheritance. Trying to pretend it does is only going to make things difficult. Rework your solution to make use of the available methods of composition instead.

    – JimB
    Jan 20 at 15:16











  • @JimB Ok. I'll dig into it. From your perspective: Can composition solve this problem or do I need to re-think the structure completely?

    – xsigndll
    Jan 20 at 15:33






  • 1





    You’re trying to solve your problem with inheritance. I’m sure there’s alterntive ways to solve your problem (there are lots of non-OOP languages), but you’re only describing your proposed solution, rather than an actual problem statement.

    – JimB
    Jan 20 at 17:00














-1












-1








-1








I'm facing a Golang begginers problem, and I don't know how to solve it correctly. Could you please help me?



Info: Even though this is against the concept of Go (not trying to be an OOP language) I'd like to discuss some solutions still.



I'd like to know the outer/parent struct name within the receiver/child. Please have a look at the following code (playground: 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"?
}


It displays "Parent", although the struct is a "Child". Can anyone tell me how to get the correct struct name? I've seen one 'solution' in another stackoverflow topic that works 'correctly' (Go - get parent struct), but I don't think this is a good solution.










share|improve this question
















I'm facing a Golang begginers problem, and I don't know how to solve it correctly. Could you please help me?



Info: Even though this is against the concept of Go (not trying to be an OOP language) I'd like to discuss some solutions still.



I'd like to know the outer/parent struct name within the receiver/child. Please have a look at the following code (playground: 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"?
}


It displays "Parent", although the struct is a "Child". Can anyone tell me how to get the correct struct name? I've seen one 'solution' in another stackoverflow topic that works 'correctly' (Go - get parent struct), but I don't think this is a good solution.







go






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 26 at 9:24







xsigndll

















asked Jan 20 at 15:06









xsigndllxsigndll

173119




173119








  • 6





    Go does not have inheritance. Trying to pretend it does is only going to make things difficult. Rework your solution to make use of the available methods of composition instead.

    – JimB
    Jan 20 at 15:16











  • @JimB Ok. I'll dig into it. From your perspective: Can composition solve this problem or do I need to re-think the structure completely?

    – xsigndll
    Jan 20 at 15:33






  • 1





    You’re trying to solve your problem with inheritance. I’m sure there’s alterntive ways to solve your problem (there are lots of non-OOP languages), but you’re only describing your proposed solution, rather than an actual problem statement.

    – JimB
    Jan 20 at 17:00














  • 6





    Go does not have inheritance. Trying to pretend it does is only going to make things difficult. Rework your solution to make use of the available methods of composition instead.

    – JimB
    Jan 20 at 15:16











  • @JimB Ok. I'll dig into it. From your perspective: Can composition solve this problem or do I need to re-think the structure completely?

    – xsigndll
    Jan 20 at 15:33






  • 1





    You’re trying to solve your problem with inheritance. I’m sure there’s alterntive ways to solve your problem (there are lots of non-OOP languages), but you’re only describing your proposed solution, rather than an actual problem statement.

    – JimB
    Jan 20 at 17:00








6




6





Go does not have inheritance. Trying to pretend it does is only going to make things difficult. Rework your solution to make use of the available methods of composition instead.

– JimB
Jan 20 at 15:16





Go does not have inheritance. Trying to pretend it does is only going to make things difficult. Rework your solution to make use of the available methods of composition instead.

– JimB
Jan 20 at 15:16













@JimB Ok. I'll dig into it. From your perspective: Can composition solve this problem or do I need to re-think the structure completely?

– xsigndll
Jan 20 at 15:33





@JimB Ok. I'll dig into it. From your perspective: Can composition solve this problem or do I need to re-think the structure completely?

– xsigndll
Jan 20 at 15:33




1




1





You’re trying to solve your problem with inheritance. I’m sure there’s alterntive ways to solve your problem (there are lots of non-OOP languages), but you’re only describing your proposed solution, rather than an actual problem statement.

– JimB
Jan 20 at 17:00





You’re trying to solve your problem with inheritance. I’m sure there’s alterntive ways to solve your problem (there are lots of non-OOP languages), but you’re only describing your proposed solution, rather than an actual problem statement.

– JimB
Jan 20 at 17:00












3 Answers
3






active

oldest

votes


















3














GetStructName is a method of the type Parent not Child, also Golang does not have inheritance, instead there is struct embedding (also there is interface embedding), which is sort of like inheritance, but with a key difference:




When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.




This basically means that when you call GetStructName, the receiver of the method is Parent (the inner or embedded type), and not Child.



This is fundamentally different from the typical class inheritance, and it explains the behaviour you're seeing.



It's well documented here.






share|improve this answer
























  • Ok - thank you. I think I want to go with the head through the wall when trying to use OOP in Go. But it still feels "right" to do it though :-)

    – xsigndll
    Jan 21 at 8:16





















0














While Daniel's answer above answers the "why" of it, you can still "sorta" get the behaviour you are probably looking for via (a slightly ugly):



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())
}


(playground: https://play.golang.org/p/qEtoEulFSPy )



EDIT: Added an interface that these types can implement so as to make the code more generic.






share|improve this answer


























  • That was one of my "solutions" as well, but this one implied writing the same method into every child over and over again. I may have to understand the concept of compostion better and see if I can rework the code towards the go-concept.

    – xsigndll
    Jan 20 at 15:28













  • I added an interface to the above code to make it a bit generic so that you can now use the interface in functions that must implement this name returning function. Nevertheless, like you said, composition would be the way to go.

    – balajeerc
    Jan 20 at 15:34



















0














For completeness I wanted to share my solution to it (Playground: https://play.golang.org/p/tUhlz_o8Z7V).



As described in my initial question, the idea is from Go - get parent struct .



It's also related to a Go2 request that I've seen here: https://github.com/golang/go/issues/28254



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
//
//---





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54277755%2fget-outer-parent-struct-name%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    GetStructName is a method of the type Parent not Child, also Golang does not have inheritance, instead there is struct embedding (also there is interface embedding), which is sort of like inheritance, but with a key difference:




    When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.




    This basically means that when you call GetStructName, the receiver of the method is Parent (the inner or embedded type), and not Child.



    This is fundamentally different from the typical class inheritance, and it explains the behaviour you're seeing.



    It's well documented here.






    share|improve this answer
























    • Ok - thank you. I think I want to go with the head through the wall when trying to use OOP in Go. But it still feels "right" to do it though :-)

      – xsigndll
      Jan 21 at 8:16


















    3














    GetStructName is a method of the type Parent not Child, also Golang does not have inheritance, instead there is struct embedding (also there is interface embedding), which is sort of like inheritance, but with a key difference:




    When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.




    This basically means that when you call GetStructName, the receiver of the method is Parent (the inner or embedded type), and not Child.



    This is fundamentally different from the typical class inheritance, and it explains the behaviour you're seeing.



    It's well documented here.






    share|improve this answer
























    • Ok - thank you. I think I want to go with the head through the wall when trying to use OOP in Go. But it still feels "right" to do it though :-)

      – xsigndll
      Jan 21 at 8:16
















    3












    3








    3







    GetStructName is a method of the type Parent not Child, also Golang does not have inheritance, instead there is struct embedding (also there is interface embedding), which is sort of like inheritance, but with a key difference:




    When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.




    This basically means that when you call GetStructName, the receiver of the method is Parent (the inner or embedded type), and not Child.



    This is fundamentally different from the typical class inheritance, and it explains the behaviour you're seeing.



    It's well documented here.






    share|improve this answer













    GetStructName is a method of the type Parent not Child, also Golang does not have inheritance, instead there is struct embedding (also there is interface embedding), which is sort of like inheritance, but with a key difference:




    When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.




    This basically means that when you call GetStructName, the receiver of the method is Parent (the inner or embedded type), and not Child.



    This is fundamentally different from the typical class inheritance, and it explains the behaviour you're seeing.



    It's well documented here.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 20 at 15:21









    Daniel Conde MarinDaniel Conde Marin

    5,73242336




    5,73242336













    • Ok - thank you. I think I want to go with the head through the wall when trying to use OOP in Go. But it still feels "right" to do it though :-)

      – xsigndll
      Jan 21 at 8:16





















    • Ok - thank you. I think I want to go with the head through the wall when trying to use OOP in Go. But it still feels "right" to do it though :-)

      – xsigndll
      Jan 21 at 8:16



















    Ok - thank you. I think I want to go with the head through the wall when trying to use OOP in Go. But it still feels "right" to do it though :-)

    – xsigndll
    Jan 21 at 8:16







    Ok - thank you. I think I want to go with the head through the wall when trying to use OOP in Go. But it still feels "right" to do it though :-)

    – xsigndll
    Jan 21 at 8:16















    0














    While Daniel's answer above answers the "why" of it, you can still "sorta" get the behaviour you are probably looking for via (a slightly ugly):



    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())
    }


    (playground: https://play.golang.org/p/qEtoEulFSPy )



    EDIT: Added an interface that these types can implement so as to make the code more generic.






    share|improve this answer


























    • That was one of my "solutions" as well, but this one implied writing the same method into every child over and over again. I may have to understand the concept of compostion better and see if I can rework the code towards the go-concept.

      – xsigndll
      Jan 20 at 15:28













    • I added an interface to the above code to make it a bit generic so that you can now use the interface in functions that must implement this name returning function. Nevertheless, like you said, composition would be the way to go.

      – balajeerc
      Jan 20 at 15:34
















    0














    While Daniel's answer above answers the "why" of it, you can still "sorta" get the behaviour you are probably looking for via (a slightly ugly):



    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())
    }


    (playground: https://play.golang.org/p/qEtoEulFSPy )



    EDIT: Added an interface that these types can implement so as to make the code more generic.






    share|improve this answer


























    • That was one of my "solutions" as well, but this one implied writing the same method into every child over and over again. I may have to understand the concept of compostion better and see if I can rework the code towards the go-concept.

      – xsigndll
      Jan 20 at 15:28













    • I added an interface to the above code to make it a bit generic so that you can now use the interface in functions that must implement this name returning function. Nevertheless, like you said, composition would be the way to go.

      – balajeerc
      Jan 20 at 15:34














    0












    0








    0







    While Daniel's answer above answers the "why" of it, you can still "sorta" get the behaviour you are probably looking for via (a slightly ugly):



    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())
    }


    (playground: https://play.golang.org/p/qEtoEulFSPy )



    EDIT: Added an interface that these types can implement so as to make the code more generic.






    share|improve this answer















    While Daniel's answer above answers the "why" of it, you can still "sorta" get the behaviour you are probably looking for via (a slightly ugly):



    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())
    }


    (playground: https://play.golang.org/p/qEtoEulFSPy )



    EDIT: Added an interface that these types can implement so as to make the code more generic.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 20 at 15:32

























    answered Jan 20 at 15:26









    balajeercbalajeerc

    1,85432441




    1,85432441













    • That was one of my "solutions" as well, but this one implied writing the same method into every child over and over again. I may have to understand the concept of compostion better and see if I can rework the code towards the go-concept.

      – xsigndll
      Jan 20 at 15:28













    • I added an interface to the above code to make it a bit generic so that you can now use the interface in functions that must implement this name returning function. Nevertheless, like you said, composition would be the way to go.

      – balajeerc
      Jan 20 at 15:34



















    • That was one of my "solutions" as well, but this one implied writing the same method into every child over and over again. I may have to understand the concept of compostion better and see if I can rework the code towards the go-concept.

      – xsigndll
      Jan 20 at 15:28













    • I added an interface to the above code to make it a bit generic so that you can now use the interface in functions that must implement this name returning function. Nevertheless, like you said, composition would be the way to go.

      – balajeerc
      Jan 20 at 15:34

















    That was one of my "solutions" as well, but this one implied writing the same method into every child over and over again. I may have to understand the concept of compostion better and see if I can rework the code towards the go-concept.

    – xsigndll
    Jan 20 at 15:28







    That was one of my "solutions" as well, but this one implied writing the same method into every child over and over again. I may have to understand the concept of compostion better and see if I can rework the code towards the go-concept.

    – xsigndll
    Jan 20 at 15:28















    I added an interface to the above code to make it a bit generic so that you can now use the interface in functions that must implement this name returning function. Nevertheless, like you said, composition would be the way to go.

    – balajeerc
    Jan 20 at 15:34





    I added an interface to the above code to make it a bit generic so that you can now use the interface in functions that must implement this name returning function. Nevertheless, like you said, composition would be the way to go.

    – balajeerc
    Jan 20 at 15:34











    0














    For completeness I wanted to share my solution to it (Playground: https://play.golang.org/p/tUhlz_o8Z7V).



    As described in my initial question, the idea is from Go - get parent struct .



    It's also related to a Go2 request that I've seen here: https://github.com/golang/go/issues/28254



    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
    //
    //---





    share|improve this answer






























      0














      For completeness I wanted to share my solution to it (Playground: https://play.golang.org/p/tUhlz_o8Z7V).



      As described in my initial question, the idea is from Go - get parent struct .



      It's also related to a Go2 request that I've seen here: https://github.com/golang/go/issues/28254



      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
      //
      //---





      share|improve this answer




























        0












        0








        0







        For completeness I wanted to share my solution to it (Playground: https://play.golang.org/p/tUhlz_o8Z7V).



        As described in my initial question, the idea is from Go - get parent struct .



        It's also related to a Go2 request that I've seen here: https://github.com/golang/go/issues/28254



        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
        //
        //---





        share|improve this answer















        For completeness I wanted to share my solution to it (Playground: https://play.golang.org/p/tUhlz_o8Z7V).



        As described in my initial question, the idea is from Go - get parent struct .



        It's also related to a Go2 request that I've seen here: https://github.com/golang/go/issues/28254



        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
        //
        //---






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 21 at 18:43

























        answered Jan 21 at 18:18









        xsigndllxsigndll

        173119




        173119






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54277755%2fget-outer-parent-struct-name%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Liquibase includeAll doesn't find base path

            How to use setInterval in EJS file?

            Petrus Granier-Deferre