I have a struct Person.
type Person struct {
Firstname string
Lastname string
Years uint8
}
Then I have two instances of this struct, PersonA and PersonB.
PersonA := {"", "Obama", 6}
PersonB := {"President", "Carter", 8}
I want to write a function that copies the values from PersonA to PersonB given some condition for each field (i.e. non-empty). I know how to do this by hard-coding the field names, but I want a function that works even if I change the Person struct.
I know Go reflections is helpful, but the issue is getting and setting the values requires knowing the types, if you want to use something like SetInt. But is there is a "simple" way to do this?
** Javascript analogy ** In Javascript, you could just do a (for property in someObject) to loop through.
(for propt in personA) {
if personA[propt] != "" {
// do something
personB[propt] = personA[propt]
}
}
Options I've ruled out:
Keeping track of the fields in each struct in a map, then using a combination of FieldByName and the collection of Set* functions in the reflect pkg.
Creating a loop through the fields of Person manually (below). Because I want to do this type of "update" for many other structs (School, Animals, etc...)
if PersonA.Firstname != "" { PersonB.Firstname = PersonA.Firstname }
...
if PersonA.Years != "" { PersonB.Years = PersonA.Years }
The question below gets me half-way there, but still isn't extensible to all structs for which I want to utilize this "update" function.
in golang, using reflect, how do you set the value of a struct field?
** Other Helpful Links ** GoLang: Access struct property by name
Use
reflect.ValueOf()
to convert to concrete type. After that you could use reflect.Value.SetString to set the value you want.Reflection should be all you need. This seems similar (though not identical) to "deep copy" semantics, which has been implemented at https://godoc.org/code.google.com/p/rog-go/exp/deepcopy
You should be able to adapt that to your needs, or at least take some ideas from it.
Here is the solution
f2.Set(reflect.Value(f))
is the key herehttp://play.golang.org/p/UKFMBxfbZD
You should use a
map[string]interface{}
instead, gonna be much faster (although still not as fast as you used the proper logic with actual structs).