GoでYAMLをパースするときには、go-yaml/yamlを使うのが一般的だと思うんですが、JSONもそのままUnmarshal出来るのにちょっとびっくり。 ソースコードにもJSONの文字列が一切出てこないしあまりにも当たり前に動くので、私が情弱なだけなのかとビビってるんですが 一般的に知られてる挙動なんですかね。
package main
import (
"fmt"
"gopkg.in/yaml.v2"
)
var (
jsonval = `{"key-1":"val-1","key-2":2,"key-3":{"key-3-1":"val-3-1"},"4":4}`
yamlval = `
key-1: val-1
key-2: 2
key-3:
key-3-1: val-3-1
4: 4
`
)
func main() {
ret1 := make(map[string]interface{})
yaml.Unmarshal([]byte(jsonval), &ret1)
fmt.Printf("%#v\n", ret1)
// map[string]interface {}{"key-1":"val-1", "key-2":2, "key-3":map[interface {}]interface {}{"key-3-1":"val-3-1"}, "4":4}
ret2 := make(map[string]interface{})
yaml.Unmarshal([]byte(yamlval), &ret2)
fmt.Printf("%#v\n", ret2)
// map[string]interface {}{"key-1":"val-1", "key-2":2, "key-3":map[interface {}]interface {}{"key-3-1":"val-3-1"}, "4":4}
}
余談: map[interface{}]interface{}
go-yamlで、構造体に定義できないYAMLのUnmarshal結果ってmap[interface{}]interface{}になっちゃって扱いづらいんですよね(一応、一階層目だけならmap[string]interface{}を引数に渡せば出来ますが)。
なんですが、yamlとjsonの相互変換を上手くやってくれるパッケージがあって、yamlをUnmarshalした時にmap[string]interface{}に変換してくれる出来る奴で、そのライブラリを眺めてて気づきました。
package main
import (
"fmt"
"github.com/ghodss/yaml"
)
var (
jsonval = `{"key-1":"val-1","key-2":2,"key-3":{"key-3-1":"val-3-1"},"4":4}`
yamlval = `
key-1: val-1
key-2: 2
key-3:
key-3-1: val-3-1
4: 4
`
)
func main() {
ret1 := make(map[string]interface{})
yaml.Unmarshal([]byte(jsonval), &ret1)
fmt.Printf("%#v\n", ret1)
// map[string]interface {}{"4":4, "key-1":"val-1", "key-2":2, "key-3":map[string]interface {}{"key-3-1":"val-3-1"}}
ret2 := make(map[string]interface{})
yaml.Unmarshal([]byte(yamlval), &ret2)
fmt.Printf("%#v\n", ret2)
// map[string]interface {}{"key-1":"val-1", "key-2":2, "key-3":map[string]interface {}{"key-3-1":"val-3-1"}, "4":4}
}
このライブラリもなかなかマッチョで、go-yamlのラッパーなんですがMarshal時はjson.Marshal -> yaml.Unmarshal -> yaml.Marshal
、Unmarshal時はyaml.Unmarshal -> json.Marshal -> json.Unmarshal
と何を言っているかわからねぇ状態ですが、JSONのタグやMarshaler等をそのまま流用出来るメリットが有り、kubernetesとかでも使われていてちゃんと動きます。詳しくはこちら。
パフォーマンスに関しては、コンフィグのロードとかで起動時に1回呼ばれるとかがメインなら問題にならないでしょう。