JSON エンコーディングを使用して同一の構造のフィールドをマージする
Go プログラミングの領域では、同じ構造の 2 つの構造からフィールドをマージするタスクタイプが頻繁に出てきます。
type Config struct { path string id string key string addr string size uint64 } var DefaultConfig = Config{"", "", "", "", 0}
のようなデフォルトの構成と、
var FileConfig = Config{"", "file_id", "", "file_addr", 0}
のようなファイルからロードされた構成があるシナリオを考えてみましょう。目的は、これら 2 つの構成をマージすることです。その結果、両方の構造体の値が保持され、FileConfig が DefaultConfig の値を上書きします。ただし、FileConfig にはすべてのフィールドが含まれているわけではありません。
当初、このタスクにリフレクションを利用することを検討しました。
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 パッケージの機能を活用することです。
encoding/json パッケージは、JSON データを事前定義された Go 構造体にアンマーシャリングする簡単なメカニズムを提供します。この手法を利用すると、構成をエレガントにマージできます。
import ( "encoding/json" "strings" ) const fileContent = `{"id":"file_id","addr":"file_addr","size":100}` func unmarshalConfig(conf *Config, content string) error { return json.NewDecoder(strings.NewReader(content)).Decode(conf) } func mergeConfigs(defConfig *Config, fileConfig *Config) error { if err := unmarshalConfig(defConfig, fileContent); err != nil { return err } for _, v := range fileConfig { defConfig[v.key] = v.value } return nil }
このソリューションでは、fileConfig がデフォルトの構成にアンマーシャリングされます。エンコーディング/json パッケージは、欠損値 (デフォルトでゼロ値になる) やデフォルト値をオーバーライドするファイル指定の値など、フィールド値の設定の複雑さをすべて処理します。
アンマーシャリングを利用することで、シンプルな設定を実現します。同じタイプの構造をマージする効率的なソリューションで、設定されている FileConfig フィールドがデフォルト値よりも優先されるようにします。
以上がJSON エンコーディングを使用して同じタイプの Go 構造体を効率的にマージするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。