KDOC 95: なぜjson.Unmarshalの引数はバイト列なのか

この文書のステータス

  • 作成
    • 2024-02-16 貴島
  • レビュー
    • 2024-02-25 貴島

概要

GoでJSONをデシリアライズするときに使う関数のシグネチャはこうだ。

func Unmarshal(data []byte, v any) error {}

引数は[]byteで、バイトスライスだ。どうして文字列ではないのか、違いは何かを考えた。が、なぜそうなったのかは見つけられず、自分の持っている知識ではよくわからなかった。

違い

stringと[]byteの違いは何か。本質的にはどちらもバイト列だ。文字列はイミュータブルで、バイトスライスはミュータブルという点は違う。したがってデータが変わるときはバイトスライスのほうがコストを低くできる。文字列だとメモリをアローケーションして作り直すしかないから。文字列だと特定のケースで遅くなる可能性があるから、バイトスライスにしている、などどうだろう。

コンピュータ内部やネットワーク間ではバイト列で処理してるだろうから、[]byteのほうが低レイヤで汎用的ではある。標準ライブラリなどではバイト列を受け渡しする関数は多いので、互換性を保ちやすそうだ。また、Goは書く量がやや増えるのを許容して汎用性を求める、ようなデザインをしているように見えるので自然に見える。が、確かめる方法はわからない。