I have a function which accepts slice of values and fields as a set of optional parameters and the function maps each value to a field and returns error if any to the caller as in below
func Unmarshall(source []interface{}, dest ...interface{}) error {
if len(source) != len(dest) {
return errors.New("source and destination doesn't match")
}
for i, s := range source {
dest[i] = s
}
return nil
}
and below the code I have for the caller
for _, r := range rows.Values {
item := entity.Item{}
e :=Unmarshall(r,
&item.Name,
&item.Description,
&item.AddedUTCDatetime,
&item.ModifiedUTCDatetime)
if e == nil {
items = append(items, item)
}
}
But the issue with the above is item.Name,item.Description, &item.AddedUTCDatetime, &item.ModifiedUTCDatetime
doesn't retain the values set in the Unmarshall func
even though I passed in the pointer to the fields.
Is there anything wrong with the above code?
This one takes care of all types
for i, s := range source {
so := reflect.ValueOf(s)
if !reflect.DeepEqual(so, reflect.Zero(reflect.TypeOf(so)).Interface()) {
reflect.ValueOf(dest[i]).Elem().Set(so)
}
}
Is there anything wrong with the above code?
Yes. You're discarding the pointers and are simply overwriting them with new values. To set value that pointer points to, you must dereference it. Could look something like this in your case:
for i, s := range source {
str, ok := dest[i].(*string)
if ok {
*str = s.(string)
}
}