Using reflection to build out a struct...

498 views
Skip to first unread message

John

unread,
Jul 27, 2013, 2:04:29 AM7/27/13
to golan...@googlegroups.com
So.....

Forgetting the questions of why I want to do this, I'm hoping someone will have some insight on how to so something.

Say I have the following:
=========================
type Root struct {
  Name string
  Leaf *Leaf1
}

type Leaf1 struct {
  Leaf *Leaf2
}

type Leaf2 struct {}
=========================

I want to be able to use refletion to build this, given only an empty Root{} variable:

top := Root{
  Name: "",
  Leaf: &Leaf1{
    Leaf: &Leaf2{},
  },
}
=========================

Walking Root and figuring out what's there is easy, but I'm having trouble with assigning Root.Leaf = &Leaf1{}.

I was experimenting with:

top := Root{}
var p unsafe.Pointer                                                           
ptr := reflect.NewAt(reflect.TypeOf(top.Leaf).Elem(), p)                         
reflect.ValueOf(unsafe.Pointer(top.Leaf)).SetPointer(unsafe.Pointer(ptr.Pointer()))  // Wasn't sure if I could use "p" here, but it has the same error.

panic: reflect: reflect.Value.SetPointer using unaddressable value

I've played with a few (dozen) variations, but what I can't seem to get is:

How do I use reflection to get a reflect.Value object that represents the value a pointer points to without knowing it before hand(aka how can I determine Root.Leaf points to Leaf1{}, and create a "Leaf{}" that I can then assign Root.Leaf to points to (wheww).

Anyone got a way?


Julian Phillips

unread,
Jul 27, 2013, 5:39:27 AM7/27/13
to John, golan...@googlegroups.com
No need to involve unsafe, especially in ways that hide the actual
types from the reflect code that you're trying to use.

Heres a basic example, with very little error checking:
http://play.golang.org/p/ENQm5zMxJv

I expect that encoding/json and similar libraries would provide a
richer source of examples of using reflect to fill things out (not
actually read the code).

--
Julian

Tad Glines

unread,
Jul 27, 2013, 12:17:34 PM7/27/13
to John, golang-nuts
Here's an example of how to do it: http://play.golang.org/p/57aQRTabTc

-Tad




--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Tad Glines

unread,
Jul 27, 2013, 12:20:33 PM7/27/13
to John, golang-nuts
I replied before seeing Julian's reply. His is a far more complete answer.

Jan Mercl

unread,
Jul 27, 2013, 12:30:33 PM7/27/13
to John, golang-nuts
On Sat, Jul 27, 2013 at 8:04 AM, John <johns...@gmail.com> wrote:
> Walking Root and figuring out what's there is easy, but I'm having trouble
> with assigning Root.Leaf = &Leaf1{}.

Types have no accessible fields, only instances do. Reflection nor
unsafe can help in this. Perhaps you meant `top.Leaf = &Leaf1`
instead? That can be done directly:
http://play.golang.org/p/gLpXbNesUt

-j

jd...@google.com

unread,
Jul 27, 2013, 1:48:40 PM7/27/13
to golan...@googlegroups.com, John
Thanks guys.  I'd tried a doing something similar with Indirect, but got lost somewhere and thought I had gone down the wrong road.

These examples were exactly what I needed.  Thank you very much for taking the time to help.

--John 
Reply all
Reply to author
Forward
0 new messages