概要
標準パッケージである encoding/json
を使います
map を json に変換したり json 文字列から map および struct を生成したりできます
環境
- macOS 10.14.4
- golang 1.11.5
map to json
json.Marshal()
を使います
package main
import (
"encoding/json"
"fmt"
)
func main() {
map1 := map[string]interface{}{
"name": "hawksnowlog",
"age": 20,
}
j1, err := json.Marshal(map1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(j1))
}
struct to json
map を json に変換しましたが struct でも同じようにできます
package main
import (
"encoding/json"
"fmt"
)
type MyStruct struct {
Name string
Age int
}
func main() {
st1 := MyStruct{
Name: "hawksnowlog",
Age: 20,
}
j1, err := json.Marshal(st1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(j1))
}
ただこの場合は struct のメンバ名に合わせて出力される json のキーも先頭が大文字になるので注意してください
json (string) to map
json.Unmarshal()
を使います
第一引数にバイト配列を第二引数に変換先の変数のアドレスを指定します
第二引数で指定した型に変換できない場合は err になります
package main
import (
"encoding/json"
"fmt"
)
func main() {
j1 := `{"name":"hawksnowlog","age":20}`
var map1 map[string]interface{}
err := json.Unmarshal([]byte(j1), &map1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(map1["name"].(string))
fmt.Println(map1["age"].(float64))
// fmt.Println(int(map1["age"].(float64))) to int
}
json (string) to struct
先程は map に Unmarshal しましたが今回は struct に変換します
おそらくこれが一番安全なやり方だと思います
package main
import (
"encoding/json"
"fmt"
)
type MyStruct struct {
Name string
Age int
}
func main() {
j1 := `{"name":"hawksnowlog","age":20}`
var st1 MyStruct
err := json.Unmarshal([]byte(j1), &st1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(st1.Name)
fmt.Println(st1.Age)
}
対応しないメンバが存在する場合はそれぞれの型のデフォルト値が設定されます
バインドするフィールド名を指定する
デフォルトは struct のメンバ名に該当するフィールドを json から探してそれにバインドします
メンバ名とフィールド名が異なる場合は指定することも可能です
package main
import (
"encoding/json"
"fmt"
)
type MyStruct struct {
Name string `json:"account_name"`
Age int
}
func main() {
j1 := `{"account_name":"hawksnowlog","age":20}`
var st1 MyStruct
err := json.Unmarshal([]byte(j1), &st1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(st1.Name)
fmt.Println(st1.Age)
}
デフォルト値を設定する
先程、該当するフィールド名がない場合は各型のデフォルト値が設定されると説明しました
設定されるデフォルト値を独自で設定したい場合は構造体を生成するときに指定することができます
package main
import (
"encoding/json"
"fmt"
)
type MyStruct struct {
Name string `json:"account_name"`
Age int `json:"account_age"`
}
func main() {
j1 := `{"account_name":"hawksnowlog","age":20}`
st1 := MyStruct{
Age: 30,
}
err := json.Unmarshal([]byte(j1), &st1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(st1.Name)
fmt.Println(st1.Age)
}
上記の場合、json 内に「account_age」がないので Age=0 になるところですが構造体を生成するときに Age=30 で初期化しているため json.Unmarshal
後の値も 30 になっています
最後に
json.Marshal
するときは map や構造体をそのまま入れるjson.Unmarshal
するときは変換先の map や構造体と一緒にバイト配列の json を入れる
と覚えておけば大抵の場合は対応できると思います
0 件のコメント:
コメントを投稿