Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Value type to Map in Golang?

Tags:

reflection

go

I'm getting this return value from a function call in the "reflect" package:

< map[string]string Value >.

Wondering if I can access the actual map inside the return value and if so, how?

EDIT:

So this is where I'm making the call which returns the Value object. It returns [< map[string]string Value >] to which I grab the first object in that array. However, I'm not sure how to convert [< map[string]string Value >] into a regular map.

view_args := reflect.ValueOf(&controller_ref).MethodByName(action_name).Call(in)
like image 632
user1493543 Avatar asked Dec 21 '13 00:12

user1493543


2 Answers

Most reflect Value objects can be converted back to a interface{} value using the .Interface() method.

After obtaining this value, you can assert it back to the map you want. Example (play):

m := map[string]int{"foo": 1, "bar": 3}
v := reflect.ValueOf(m)
i := v.Interface()
a := i.(map[string]int)

println(a["foo"]) // 1

In the example above, m is your original map and v is the reflected value. The interface value i, acquired by the Interface method is asserted to be of type map[string]int and this value is used as such in the last line.

like image 199
nemo Avatar answered Sep 28 '22 19:09

nemo


To turn the value in a reflect.Value into an interface{}, you use iface := v.Interface(). Then, to access that, you use a type assertion or type switch.

If you know you're getting a map[string]string the assertion is simply m := iface.(map[string]string). If there's a handful of possibilities, the type switch to handle them all looks like:

switch item := iface.(type) {
case map[string]string:
    fmt.Println("it's a map, and key \"key\" is", item["key"])
case string:
    fmt.Println("it's a string:", item)
default:
    // optional--code that runs if it's none of the above types
    // could use reflect to access the object if that makes sense
    // or could do an error return or panic if appropriate
    fmt.Println("unknown type")
}

Of course, that only works if you can write out all the concrete types you're interested out in the code. If you don't know the possible types at compile time, you have to use methods like v.MapKeys() and v.MapIndex(key) to work more with the reflect.Value, and, in my experience, that involves a long time looking at the reflect docs and is often verbose and pretty tricky.

like image 26
twotwotwo Avatar answered Sep 28 '22 20:09

twotwotwo