テストのフィクスチャなどで、JSONを雑に書きたくなることがあるのだけど、
文字列で定義するとJSONとしての構文チェックができず不便だ。trailing commaとか、クオートの不備とかを気にして書かなくてはいけない。
js := `{
"baa": {
"a": 1,
"b": 1.9,
"c": "abc"
},
"foo": {
"baa": "muu",
"bababa": "gagaga"
}
}`
なので、Goとして構造を定義して、json.Marshal()したくなる。
json.Marshalは構造体を渡すことも多いが、雑に map[string]interface{}
を渡しても動作する。これを使って書いていくとよい。
tips
-
map[string]interface{}
だと長いので、適当に型を定義して使うと便利。 -
json.Marshal
はエラーが発生する可能性があるが、自分でコード中で定義したjson構造がバグってたらどうしようもないので、エラーをpanic化してしまう雑な関数を定義してしまうのも便利。 -
json.Indent
でインデントするのもいいぞ -
[]bytes
で扱うかstring
で扱うかは状況によるので適宜切り替えてください。
package main
import (
"bytes"
"encoding/json"
"fmt"
)
type object map[string]interface{}
type oo map[string]object
func MustJsonString(obj interface{}) string {
b, err := json.Marshal(obj)
if err != nil {
panic(err)
}
var out bytes.Buffer
err = json.Indent(&out, b, "", " ")
if err != nil {
panic(err)
}
return out.String()
}
func main() {
js := oo{
"foo": {
"baa": "muu",
"bababa": "gagaga",
},
"baa": {
"a": 1,
"b": 1.9,
"c": "abc",
},
}
fmt.Println(MustJsonString(js))
}