json.Encoder は出力の末尾に改行をつける
Last Modified:
Tags:
go
json.Marshal と json.Encoder の微妙な違い
json.Encoder
は生成した JSON の末尾に改行を追加します。json.Marshal
は追加しません。
以下のコードと出力の通りです。スライスの末尾の 10 に注目。
package main
import (
"bytes"
"encoding/json"
"fmt"
)
func main() {
m := map[string]string{
"hello": "world",
}
fmt.Println("json.Encoder")
b := new(bytes.Buffer)
json.NewEncoder(b).Encode(m)
fmt.Println("========")
fmt.Printf("%s\n", b.Bytes())
fmt.Println("========")
fmt.Printf("%v\n", b.Bytes())
fmt.Println("")
fmt.Println("json.Marshal")
buf, _ := json.Marshal(m)
fmt.Println("========" )
fmt.Printf("%s\n", buf)
fmt.Println("========")
fmt.Printf("%v\n", buf)
}
json.Encoder
========
{"hello":"world"}
========
[123 34 104 101 108 108 111 34 58 34 119 111 114 108 100 34 125 10]
json.Marshal
========
{"hello":"world"}
========
[123 34 104 101 108 108 111 34 58 34 119 111 114 108 100 34 125]
どちらも JSON として合法なので、Web API のレスポンスなどとして使う際は問題ありません。
しかし、例えば json.Marshal
を使っている関数のテストで、期待する出力を json.Encoder
で作ってしまうと微妙にハマるかもしれません。私はハマりました。
理由
json.Encoder
は io.Writer
を引数に取り、TCP ソケットやファイルなどに何度でも書き込める設計です。参考文献の Stack Overflow によると、区切りの改行があると見やすく、また一つの JSON の終わりを改行によって判定できるようになることが理由らしいです。
まぁそうですね。