gogo-reflect

How to use reflect to set the value of a map on a struct?


In Go, how can I use the reflect package to set the value of a map?

package main

import (
    "reflect"
)

type Mapped struct {
    M map[string]string
}
func main() {

    m := map[string]string{"A":"VA", "B": "VB"}
    mv := reflect.ValueOf(m)

    mapped := Mapped{}
    rv := reflect.ValueOf(mapped)

    f := rv.FieldByName("M")
    // f.Set(mv) doesn't work
}

The only methods of Value I see pertaining to maps are MapIndex,MapKeys, MapRange and SetMapIndex (which panics if the map is nil).

I can't seem to set the Addr, as maps are not addressable. I'm not sure how to assign m above to mapped.M.


Solution

  • You can get an addressable value for your map by replacing:

    rv := reflect.ValueOf(mapped)
    

    with:

    rv := reflect.ValueOf(&mapped).Elem()
    

    Then you can just call:

    f := rv.FieldByName("M") 
    f.Set(mv)
    

    as before.

    Taking the value of a pointer and then using indirection to get at the pointed-to value is what makes the difference. Otherwise reflect.ValueOf gets a non-addressable copy of your struct, just like any other function would.