Re: How can a method get receiver's embedded attribute?

261 views
Skip to first unread message

Thomas Kappler

unread,
Dec 18, 2012, 7:25:44 AM12/18/12
to golan...@googlegroups.com, i90...@gmail.com
EmbeddedAttr is not defined in your code sample. What is it supposed to be? Can you make an example on play.golang.org?


On Tuesday, December 18, 2012 12:23:24 PM UTC+1, i90...@gmail.com wrote:
Hi, all. I want to get receiver's embedded attribute in a method, for example:

package main

import (
        "fmt"
)

type MyInt int

func (i *MyInt)PrintEmbeddedAttr() {
        fmt.Println(EmbeddedAttr)
}

type Point struct {
        x, y MyInt
}

type NamedPoint struct {
        name string
        Point
}

func main() {
        var i  MyInt
        var p  Point
        var np NamedPoint

        i.PrintEmbeddedAttr()   // nil
        p.x.PrintEmbeddedAttr() // method should output "Point.x"
        np.x.PrintEmbeddedAttr() // method should output "NamedPoint.Point.x"
}


How can I do it?

Volker Dobler

unread,
Dec 18, 2012, 7:28:45 AM12/18/12
to golan...@googlegroups.com, i90...@gmail.com
IMHO: You can't, not even with reflection.
Why would you do such things?

V.

minux

unread,
Dec 18, 2012, 8:41:56 AM12/18/12
to Volker Dobler, golan...@googlegroups.com, i90...@gmail.com
On Tue, Dec 18, 2012 at 8:28 PM, Volker Dobler <dr.volke...@gmail.com> wrote:
IMHO: You can't, not even with reflection.
No, it could be done because reflect.StructField type contains a field named Anonymous.

Volker Dobler

unread,
Dec 18, 2012, 8:49:44 AM12/18/12
to golan...@googlegroups.com, Volker Dobler, i90...@gmail.com
Oh, cool. Thanks!

minux

unread,
Dec 18, 2012, 9:43:29 AM12/18/12
to Jacky Lau, Volker Dobler, golan...@googlegroups.com

On Tue, Dec 18, 2012 at 10:41 PM, Jacky Lau <i90...@gmail.com> wrote:
I can print all field of a struct by using reflect package, but I can't find a way to find out whether the receiver is embedded in other struct or not in method.
oh, this is impossible. I wonder why do you want to differentiate between embedded anonymous
field and normal field?

Steven Blenkinsop

unread,
Dec 18, 2012, 11:26:12 AM12/18/12
to i90...@gmail.com, golang-nuts
It's impossible to know inside (*MyInt).PrintEmbeddedAttr whether i or *i resides in a struct (unless you explicitly encode that information in the value). The receiver is a normal parameter inside the body of the method. It carries no metadata. What is the larger problem you are trying to solve?



On Tue, Dec 18, 2012 at 6:23 AM, <i90...@gmail.com> wrote:
Hi, all. I want to get receiver's embedded attribute in a method, for example:

package main

import (
        "fmt"
)

type MyInt int

func (i *MyInt)PrintEmbeddedAttr() {
        fmt.Println(EmbeddedAttr)
}

type Point struct {
        x, y MyInt
}

type NamedPoint struct {
        name string
        Point
}

func main() {
        var i  MyInt
        var p  Point
        var np NamedPoint

        i.PrintEmbeddedAttr()   // nil
        p.x.PrintEmbeddedAttr() // method should output "Point.x"
        np.x.PrintEmbeddedAttr() // method should output "NamedPoint.Point.x"
}


How can I do it?

--
 
 

Steven Blenkinsop

unread,
Dec 18, 2012, 11:41:11 AM12/18/12
to minux, Volker Dobler, golang-nuts, i90091e
This only works from the outside, though. The original question was about doing if from inside the method, which is impossible. Also, this won't navigate through embedded pointers, which means it only works half the time. If it's changed so it does, you can create infinite recursion. A better way would be to iterate over the methods of the struct, which are finite, and then determine what fields they're called via. Unfortunately, this information isn't encoded in reflect.Method (bummer), so that approach is a no go.


--
 
 

minux

unread,
Dec 18, 2012, 11:50:40 AM12/18/12
to Steven Blenkinsop, Volker Dobler, golang-nuts, i90091e
On Wed, Dec 19, 2012 at 12:41 AM, Steven Blenkinsop <stev...@gmail.com> wrote:
This only works from the outside, though. The original question was about doing if from inside the method, which is impossible. Also, this
why? if a method want to know the receiver's embedded fields, you can use the same approach. 
you just can't know if the receiver object is embedded within another object, as I've said, in general
this is impossible.
won't navigate through embedded pointers, which means it only works half the time. If it's changed so it does, you can create infinite
right, that's why I didn't trace the pointers, however, I think technically, i think embed a pointer to another
structure doesn't qualify as a embedded struct, i.e.
type T struct { /* blah blah */ }
type T2 {
    *T
}

you can't say T2 embeds T, so I argue that my approach of not tracing the embedded pointers is
actually correct.

for example, consider the fact you can embed a unsafe.Pointer in a struct, and technically, it can
point to any type of object, so all types are embedded in this particular struct?

bryanturley

unread,
Dec 18, 2012, 12:19:45 PM12/18/12
to golan...@googlegroups.com, i90...@gmail.com


On Tuesday, December 18, 2012 5:23:24 AM UTC-6, i90...@gmail.com wrote:
Hi, all. I want to get receiver's embedded attribute in a method, for example:

package main

import (
        "fmt"
)

type MyInt int

func (i *MyInt)PrintEmbeddedAttr() {
        fmt.Println(EmbeddedAttr)
}

type Point struct {
        x, y MyInt
}

type NamedPoint struct {
        name string
        Point
}

func main() {
        var i  MyInt
        var p  Point
        var np NamedPoint

        i.PrintEmbeddedAttr()   // nil
        p.x.PrintEmbeddedAttr() // method should output "Point.x"
        np.x.PrintEmbeddedAttr() // method should output "NamedPoint.Point.x"
}


How can I do it?

 
If you manually tracked every allocation (annoying, space consuming) you could hack it, but why do you want to?

If you typed p.x.PrintEmbeddedAttr().... you already know you used p.x ... and you defined p so

Jacky Lau

unread,
Dec 18, 2012, 9:33:30 AM12/18/12
to Thomas Kappler, golan...@googlegroups.com
EmbeddedAttr is something express the embedded attribute, maybe a string, e.g. "Point.x". Of course it's pseudo.

Jacky Lau

unread,
Dec 18, 2012, 9:41:27 AM12/18/12
to minux, Volker Dobler, golan...@googlegroups.com
I can print all field of a struct by using reflect package, but I can't find a way to find out whether the receiver is embedded in other struct or not in method.



2012/12/18 minux <minu...@gmail.com>

Steven Blenkinsop

unread,
Dec 18, 2012, 3:38:56 PM12/18/12
to Jacky Lau, minux, Volker Dobler, golang-nuts
On Tue, Dec 18, 2012 at 11:50 AM, minux <minu...@gmail.com> wrote:
On Wed, Dec 19, 2012 at 12:41 AM, Steven Blenkinsop <stev...@gmail.com> wrote:
This only works from the outside, though. The original question was about doing if from inside the method, which is impossible. Also, this
why? if a method want to know the receiver's embedded fields, you can use the same approach. 
you just can't know if the receiver object is embedded within another object...

...which is what the OP was asking about. But I see now you already figured that out (for some reason my email is lagging behind the conversation, so I hadn't seen your second response). The rest of my response is talking about the original solution you posted.

right, that's why I didn't trace the pointers, however, I think technically, i think embed a pointer to another
structure doesn't qualify as a embedded struct, i.e.

<snip>
 
you can't say T2 embeds T, so I argue that my approach of not tracing the embedded pointers is
actually correct.
 
You can play with the semantics of describing it however you want, but either way, if you ignore embedded pointers, you'll miss anonymous fields whose fields might be promoted and accessible from the top level struct. Also, your approach doesn't take into consideration selector resolution, and will show anonymous fields that won't be promoted. Here's an attempt to fix those issues: http://play.golang.org/p/EcNwPL8l9c

This still doesn't help you with methods, though, since any information that might let you know which anonymous field a given method is bound to is absent from reflect.Method.

for example, consider the fact you can embed a unsafe.Pointer in a struct, and technically, it can
point to any type of object, so all types are embedded in this particular struct?

An unsafe.Pointer has no methods or fields, so the point is moot. Even with an embedded interface, only the methods in the interface itself are promoted, so you don't have to traverse it.

Jacky Lau

unread,
Dec 19, 2012, 6:06:55 AM12/19/12
to Steven Blenkinsop, golang-nuts
Thanks for everyone's enthusiasm. In simple terms, what I want is to get the container of an object:
func ContainerOf(obj interface{}) interface{}

I write a program to emulate the capability of this function: http://play.golang.org/p/TMaBrdh-ci
As you see, I just track every variable, as bryanturley proposed. This is not practical. Another way
is embedded a empty interface variable which point to the container in every struct. But it's not practical too.

I think the best way is access the container in a outside function instead of access it from embedded variable's method.



2012/12/19 Steven Blenkinsop <stev...@gmail.com>

minux

unread,
Dec 19, 2012, 6:44:07 AM12/19/12
to Jacky Lau, Steven Blenkinsop, golang-nuts

On Wednesday, December 19, 2012, Jacky Lau wrote:
Thanks for everyone's enthusiasm. In simple terms, what I want is to get the container of an object:
func ContainerOf(obj interface{}) interface{}
what problem are you trying to solve with this in general?
are there any language out there that can implement this function?
(note being able to realize this means there are differences between type a that
embedded into two different types)

Jacky Lau

unread,
Dec 21, 2012, 7:01:54 AM12/21/12
to minux, Steven Blenkinsop, golang-nuts
Sometime you may want to implement a function that do something on any struct type. One way is implement a independent function. But I want to implement it as a method of base type. Any type embedded the base type has the capability of base type. For example, base type implement a function that print container's field value, so the type which embedded base type can print itself.
But I give up now.


2012/12/19 minux <minu...@gmail.com>

Ian Lance Taylor

unread,
Dec 21, 2012, 9:34:45 AM12/21/12
to Jacky Lau, minux, Steven Blenkinsop, golang-nuts
On Fri, Dec 21, 2012 at 4:01 AM, Jacky Lau <i90...@gmail.com> wrote:
> Sometime you may want to implement a function that do something on any
> struct type. One way is implement a independent function. But I want to
> implement it as a method of base type. Any type embedded the base type has
> the capability of base type. For example, base type implement a function
> that print container's field value, so the type which embedded base type can
> print itself.
> But I give up now.

That kind of design happens when you translate C++ or Java to Go. It
doesn't work very well in Go. In Go to do this kind of thing you use
interfaces, not method inheritance.

If you really can't use interfaces, then in Go to only way to
implement that sort of idea is to keep a pointer to the parent object
in each child class. But use interfaces instead.

Ian
Reply all
Reply to author
Forward
0 new messages