Go言語(golang) 構造体やマップのマージ
構造体やマップをマージするためのGo言語のパッケージ mergo の使い方。
目次
構造体のマージ
値が空(ゼロ値)の場合に上書きされる。src
と dist
型が異なる場合はエラー src and dst must be of same type
になる。
package main import ( "fmt" "log" "github.com/imdario/mergo" ) type Config struct { Name string Age int } func main() { src := Config{ Name: "Tanaka", Age: 31, } dist := Config{ Name: "Suzuki", } if err := mergo.Merge(&dist, src); err != nil { log.Fatal(err) } // フィールドの値が空の場合のみ上書きされるので Name は上書きされず、Age のみ変更される fmt.Printf("%#v\n", dist) // main.Config{Name:"Suzuki", Age:31} }
オーバーライド
値が空でなくても上書きされる。MergeWithOverwrite
関数も定義してあるけど、内部的には Merge
関数に WithOverride
を指定してあるだけ。
package main import ( "fmt" "log" "github.com/imdario/mergo" ) type Config struct { Name string Age int } func main() { src := Config{ Name: "Tanaka", Age: 31, } dist := Config{ Name: "Suzuki", Age: 46, } // 引数に WithOverride を指定する if err := mergo.Merge(&dist, src, mergo.WithOverride); err != nil { log.Fatal(err) } fmt.Printf("%#v\n", dist) // main.Config{Name:"Tanaka", Age:31} }
マップのマージ
dist
にキーが存在しない場合と、値が空(ゼロ値)の場合に上書きされる。構造体と違って型が異なる場合でも dist
の方がゆるい場合(interface{}を使ってるという意味で)はエラーにはならない。逆だとパニックする。
package main import ( "fmt" "log" "github.com/imdario/mergo" ) func main() { src := map[string]interface{}{ "name": "Tanaka", "age": 31, } dist := map[interface{}]interface{}{ "name": "", "age": 46, } if err := mergo.Map(&dist, src); err != nil { log.Fatal(err) } // age の値はそのまま fmt.Printf("%#v\n", dist) // map[interface {}]interface {}{"age":46, "name":"Tanaka"} }
オーバーライド
値が空でない場合も src
にキー/値があれば上書きされる。構造体のオーバーライドと同じで WithOverride
を指定する。MapWithOverwrite
関数も定義してあるけど同じ。
package main import ( "fmt" "log" "github.com/imdario/mergo" ) func main() { src := map[string]interface{}{ "name": "Tanaka", "age": 31, } dist := map[interface{}]interface{}{ "age": 46, } if err := mergo.Map(&dist, src, mergo.WithOverride); err != nil { log.Fatal(err) } // dist の age も上書きされる fmt.Printf("%#v\n", dist) // map[interface {}]interface {}{"age":31, "name":"Tanaka"} }