NoahOrblog

某・福島にある大学のコンピュータ理工学部の大学生のお話。

GolangでのJSONパース備忘録

Noahです

GolangでGistにPOSTするプログラムを書いていたのですが、JSONのキーの値を変更せねばならないところで躓いたので備忘録します

f:id:NoahOrberg:20170722131801p:plain

GolangにおけるJSONの取り扱い方

基本的に構造体を使います

type Person struct {
    name string `json"name"`
    age  int    `json:"age"`
}

このように json タグを構造体の各要素に書いて、 encoding/json パッケージ内の Marshal 関数でパースすることで、JSONを生成できます

noah := Person{
    name: "NoahOrberg",
    age:  20,
}

data, err := json.Marshal(noah)
if err != nil {
    // エラーハンドリング
}

という感じで、 data[]byteJSONにパースされたデータが入ります


本題

構造体を扱う場合は、構造体のタグの値は 不変 です

ミュータブルである変数のようにあとから後付できません

タグ情報を取得する関数は reflect パッケージにありますが、再びセットし直すことはできないのです

そのため、

{
  "description" : "説明",
  "public" : false,
  "files" : {
    "hoge.txt" : {      <- ココ!
      "content" : "ファイルの中身"
    }
  }
}

上のようなGistのAPIのPayloadのようにキーにファイル名を持たせる、などには扱えません。

どうしようかと、取り敢えずIssueだけ立てて解決策が出るまで保留にしようと思ったところ、Issueを立てて数分後に @upamune さんから助言をいただきました (サンプルコードまで用意していただきありがとうございます🙇 )

f:id:NoahOrberg:20170722095125p:plain

なるほど、 map で持たせればJSONのキーの値はmapのキーの値となって変更可能になるのか。

1.のほうで map[string]File としてmapで持たせて、2.の方で詰め込んでます

このようにすることで、パースする際にキーの値を変更させることができました🎉

github.com