11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

go-yamlはJSONもUnmarshal出来る

Posted at

GoでYAMLをパースするときには、go-yaml/yamlを使うのが一般的だと思うんですが、JSONもそのままUnmarshal出来るのにちょっとびっくり。 ソースコードにもJSONの文字列が一切出てこないしあまりにも当たり前に動くので、私が情弱なだけなのかとビビってるんですが :fearful: 一般的に知られてる挙動なんですかね。

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{} :joy:

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回呼ばれるとかがメインなら問題にならないでしょう。

11
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?