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
To loop through struct types in Go , makes use of the reflect package. The Reflect package implements run-time reflection, hence allowing a program to modify objects with arbitrary types. In the above example, we define User struct type with several attributes.
In Golang, you can loop through an array using a for loop by initialising a variable i at 0 and incrementing the variable until it reaches the length of the array. In the code above, we defined an array of integers named numbers and looped through them by initialising a variable i .
A structure or struct in Golang is a user-defined type that allows to group/combine items of possibly different types into a single type. Any real-world entity which has some set of properties/fields can be represented as a struct. This concept is generally compared with the classes in object-oriented programming.
Use reflect.ValueOf()
to convert to concrete type. After that you could use reflect.Value.SetString to set the value you want.
structValue := FooBar{Foo: "foo", Bar: 10} fields := reflect.TypeOf(structValue) values := reflect.ValueOf(structValue) num := fields.NumField() for i := 0; i < num; i++ { field := fields.Field(i) value := values.Field(i) fmt.Print("Type:", field.Type, ",", field.Name, "=", value, "\n") switch value.Kind() { case reflect.String: v := value.String() fmt.Print(v, "\n") case reflect.Int: v := strconv.FormatInt(value.Int(), 10) fmt.Print(v, "\n") case reflect.Int32: v := strconv.FormatInt(value.Int(), 10) fmt.Print(v, "\n") case reflect.Int64: v := strconv.FormatInt(value.Int(), 10) fmt.Print(v, "\n") default: assert.Fail(t, "Not support type of struct") } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With