vendredi 23 novembre 2018

What is Golang reflect unaddressable value?

All in all the question is: what does unaddressable value mean? I can print it, can define its type and kind but can't set it.
In my case, I have a function that consumes a map[string]interface{} and an empty struct corresponding to this map. I want to write values from map to the struct like it does json.Unmarshall.

func i2s(data interface{}, out interface{}) error {
    var dv, ov  reflect.Value
    if reflect.TypeOf(data).String() == "reflect.Value" {
        dv = reflect.ValueOf(data)
    } else {
        dv = reflect.ValueOf(data)
    }
    if reflect.TypeOf(out).String() == "reflect.Value" {
        ov = out.(reflect.Value)
    } else {
        ov = reflect.ValueOf(out)
    }
    if dv.Kind() == reflect.Ptr {
        dv = dv.Elem()
    }
    if ov.Kind() == reflect.Ptr {
        ov = ov.Elem()
    }
    fmt.Println(ov.Field(0))
    switch dv.Kind() {
    case reflect.Map:
        for _, key := range dv.MapKeys() {
            for i := 0; i < ov.NumField(); i++ {
                if ov.Type().Field(i).Name == key.String() {
                    switch ov.Field(i).Kind() {
                    case reflect.String:
                        ov.Field(i).SetString(dv.MapIndex(key).Elem().String())
                    case reflect.Bool:
                        ov.Field(i).SetBool(dv.MapIndex(key).Elem().Bool())
                    case reflect.Int:
                        ov.Field(i).Elem().SetInt(int64(dv.MapIndex(key).Elem().Float()))
                    case reflect.Struct:
                        i2s(dv.MapIndex(key).Interface(), ov.Field(i))
                    }
                }
            }
        }
    }
    return nil
}

This works fine when I pass a

type foo struct {
    A int
    B string
    C bool
}

and write to it but when I have this struct embedded into other one and trying to call i2s recursively in

case reflect.Struct:
    i2s(dv.MapIndex(key).Interface(), ov.Field(i))

I'm starting to get unaddressed value while setting.





Aucun commentaire:

Enregistrer un commentaire