yu lei
yu lei

Reputation: 47

How to dereference a dynamic multiple level pointer?

I was trying to implement a function to print the structure tree of an interface{} with reflection and DFS.

But I find it's hard to get dereference of a multiple level pointer (NumField()can not be used with a pointer). Just like:

func Tree(i interface{}) {
  ......
}

var a = 10
var b = &a
var c = &b

Tree(c)

In my opinion, maybe:

for reflect.ValueOf(i).Kind() == reflect.Ptr {
    t := i.(reflect.Typeof(i))
    i = *t
}

could work, but it doesn't.

Is there any way to resolve this?

Upvotes: 0

Views: 288

Answers (3)

fwhez
fwhez

Reputation: 581

You're looking for reflect.Indirect(interface{}),

// Indirect returns the value that v points to.
// If v is a nil pointer, Indirect returns a zero Value.
// If v is not a pointer, Indirect returns v.
rv := reflect.Indirect(v)

Upvotes: 0

Thundercat
Thundercat

Reputation: 120941

Use the following to indirect through values:

 v := reflect.ValueOf(i)
 for v.Kind() == reflect.Ptr && !v.IsNil() {
    v = v.Elem()
 }
 // v.Interface() is nil pointer or non-pointer

Run it on the Playground

Upvotes: 1

mkopriva
mkopriva

Reputation: 38203

Using reflection you can do this:

rt := reflect.ValueOf(i).Type()
for rt.Kind() == reflect.Ptr {
    rt = rt.Elem()
}

// rt is non-pointer type

https://play.golang.com/p/YbT1p4R3_1u

Upvotes: 4

Related Questions