任務是合併兩個相同類型的結構,使得第二個結構中的欄位覆蓋第一個結構中的字段,但僅如果它們已設定。該解決方案應考慮零值的可能性。
最初的方法考慮使用反射:
func merge(default *Config, file *Config) (*Config) { b := reflect.ValueOf(default).Elem() o := reflect.ValueOf(file).Elem() for i := 0; i < b.NumField(); i++ { defaultField := b.Field(i) fileField := o.Field(i) if defaultField.Interface() != reflect.Zero(fileField.Type()).Interface() { defaultField.Set(reflect.ValueOf(fileField.Interface())) } } return default }
但是,這種方法面臨一些問題關於反射的使用以及在所有情況下檢查零值的困難。
另一個解決方案利用encoding/json套件:
conf := new(Config) // New config *conf = *defConfig // Initialize with defaults err := json.NewDecoder(strings.NewReader(fileContent)).Decode(&conf) if err != nil { panic(err) }
這個方法有幾個優點:
在給定的預設設定和檔案內容中使用此方法會產生以下輸出:
&{S1: S2:file-s2 S3: S4:def S5:file-s5}
這顯示:
以上是如何有效合併兩個相同的 Go 結構,並優先考慮第二個結構中的非零值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!