読者です 読者をやめる 読者になる 読者になる

golangで型のmappingがないjsonをいじる方法のメモ

[golang][wip]golangで型のmappingがないjsonをいじる

golangで型のmappingがないjsonをいじる時には interface{} で受け取って色々やれば良いらしい。 型でswitchできるのでどうにかなる。

memo

  • bytes.BufferはStringIO的なもの
  • 型でswitchする時mapかslicesか分かればどうにかなる
  • encoding/jsonを使っている限りJSONの順序は失われる
  • 複数行文字列のリテラルを使いたい場合にはraw stringを使う

(あとでまじめに書くかもしれない。)

以下はてきとうにJSONっぽいものを出力し直すコードを自分で書いたもの

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
)

const DATA = `
{
  "type": "person",
  "name": "foo",
  "age": 20,
  "skills": [
    {
      "type": "skil",
      "name": "bar"
    }
  ]
}
`

func Dump(d *interface{}, buf *bytes.Buffer) {
    switch v := (*d).(type) {
    case []interface{}:
        buf.WriteString("[")
        for _, sub := range v {
            Dump(&sub, buf)
            buf.WriteString(", ")
        }
        if len(v) > 0 {
            buf.Truncate(buf.Len()-2)
        }
        buf.WriteString("]")
    case map[string]interface{}:
        buf.WriteString("{")
        for k, sub := range v {
            buf.WriteString(fmt.Sprintf(`"%s"`, k))
            buf.WriteString(": ")
            Dump(&sub, buf)
            buf.WriteString(", ")
        }
        if len(v) > 0 {
            buf.Truncate(buf.Len()-2)
        }
        buf.WriteString("}")
    case string:
        buf.WriteString(fmt.Sprintf(`"%s"`, v))
    default:
        buf.WriteString(fmt.Sprintf("%v", v))
    }
}

func main() {
    var m interface{}
    json.Unmarshal([]byte(DATA), &m)
    buf := &bytes.Buffer{}
    Dump(&m, buf)
    fmt.Println(buf.String())
}