mercredi 21 novembre 2018

go ValueOf primitive returns struct

First of all I'm making a function that will write result of unmarshalling json to struct. It should looks like:

type foo struct {
    A int
    B string
    C bool
}

bar := &foo{1, "foo", true}
js, _ := json.Marshall(bar)
var tmp interface{}
json.Unmarshall(js, &tmp)
result := new(Simple)
err := i2s(tmp, result)

So the result have to be deep equal to bar. Here what I've got:

func i2s(data interface{}, out interface{}) error {
    v := reflect.ValueOf(data)
    outv := reflect.ValueOf(out)
    if outv.Kind() == reflect.Ptr {
        outv = outv.Elem()
    }
    if v.Kind() == reflect.Ptr {
        v = v.Elem()
    }
    switch v.Kind() {
    case reflect.Map:
        for _, key := range v.MapKeys() {
            for j := 0; j < outv.NumField(); j++ {
                strField := outv.Type().Field(j)
                if strField.Name == key.String() {
                    i2s(v.MapIndex(key).Elem(), outv.Field(j))
                }
            }
        }
    case reflect.Float64:
        reflect.ValueOf(out).SetInt(int64(v.Float()))
        return nil
    case reflect.String:
        reflect.ValueOf(out).SetString(v.String())
        return nil
    case reflect.Bool:
        fmt.Println("!!!!!")
        reflect.ValueOf(out).SetBool(v.Bool())
        return nil
    default:
        return errors.New("not implemented type")
    }
    return nil
}

I'm facing a problem while passing the elements of a map. If I simply print data in the begining of the function I'll get

map[A:1, B:foo, C: true]
1
foo
true

But if I print v.Kind() I'll get

map
struct
struct
struct

Why is a struct there? I've tried to fill one field like this:

for i := 0; i < simv.NumField(); i++ {
    if v.MapIndex(val).Kind() == reflect.Bool {
        simv.Field(i).SetBool(v.MapIndex(val).Elem().Bool())
    }
}

This works fine. But when I start passing variebles recursively everything breaks.





Aucun commentaire:

Enregistrer un commentaire