Merging Structs of the Same Type with Reflection or JSON Unmarshalling
In Go, you may encounter a scenario where you need to merge two structs of the same type, with values from one struct potentially overriding those in another. This article explores two approaches to achieve this: using Go's reflection capabilities or unmarshalling JSON data into a prepared default configuration.
Reflection Approach (Not Recommended)
The reflection approach, as presented below, requires checking for zero values to determine which fields to override. However, this solution is not ideal because:
<br>func merge(default <em>Config, file </em>Config) (*Config) {<br> b := reflect.ValueOf(default).Elem()<br> o := reflect.ValueOf(file).Elem()</p> <p>for i := 0; i < b.NumField(); i {</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">defaultField := b.Field(i) fileField := o.Field(i) if defaultField.Interface() != reflect.Zero(fileField.Type()).Interface() { defaultField.Set(reflect.ValueOf(fileField.Interface())) }
}
return default
}
JSON Unmarshalling Approach (Recommended)
A more elegant and flexible approach is to use Go's encoding/json package and unmarshal JSON data into a prepared default configuration. This method provides several advantages:
To demonstrate this approach:
Example code:
var defConfig = &Config{ S1: "", S2: "", S3: "abc", S4: "def", S5: "ghi", } const fileContent = `{"S2":"file-s2","S3":"","S5":"file-s5"}` err := json.NewDecoder(strings.NewReader(fileContent)).Decode(defConfig) if err != nil { panic(err) }
This solution ensures that values in the default configuration are overwritten by the values in the file configuration, providing a reliable and flexible way to merge structs of the same type.
The above is the detailed content of How Can I Efficiently Merge Two Go Structs of the Same Type?. For more information, please follow other related articles on the PHP Chinese website!