vendredi 21 août 2020

Update field of struct in function with pointer receiver for interface using reflection

I have multiple structs describing some database entries from different tables. They all implement the interface Model. All structs have an ID, however the names of the IDs are different: for example the "Location" struct has "LocationID", the Note struct has a "NoteID".. I want to write a function that is able to update all the IDs of structs that implement the Model interface:

location := Location{LocationID: 1, ...}
UpdateModelID(&location, 2)

note := Note{NoteID: 5, ...}
UpdateModelID(&note, 10)

I already tried to use reflection for this, however I did not yet get to the point where I can actually set the value of a field.

This is the code of the function so far:

func UpdateModelID(mdl *Model, id int) {
    switch reflect.TypeOf(*mdl).Kind() {
    case reflect.TypeOf(Location{}).Kind():
        reflect.ValueOf(mdl).Elem().Elem().FieldByName("LocationID").SetInt(int64(id))
    default:
        log.Panicf("Type %T is not supported", mdl)
    }
}

When running, it panics with the message:

reflect: reflect.flag.mustBeAssignable using unaddressable value

Now my question is if its actually possible to set fields of a struct, if the function only allows to receive the pointer to an interface. It would probably be easier if I wouldn't use a pointer receiver, however as I need to update a lot of entries, copying a bunch of structs back-and-fourth would hurt the performance. I already read a lot of similar questions here on stackoverflow, but unfortunately I did not really find an answer yet..





Aucun commentaire:

Enregistrer un commentaire