iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 25
2

json

json 是一種很好擴充的資料格式,格式像這樣

{
	"cId" : "A" , 
	"cType" : "English" , 
	"saddr" : { "hsnId" : "C" , "addr" : "中正路12號" } , 
	"persons" : [
		{"id" : 1 , "name" : "Daniel"},
		{"id" : 2 , "name" : "Allen"},
		{"id" : 3 , "name" : "Sam"}
	]
}

go 的 json.Unmarshal 可以把 json 字串轉成 struct,而 json.Marshal 可以將 struct 轉成 json 字串.

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Id   int    `json:"id"`
	Name string `json:name`
}

func main() {
	data := []byte(`{"id" : 1 , "name" : "Daniel"}`)
	var person Person
	json.Unmarshal(data, &person)
	fmt.Println(person)
	jsondata, _ := json.Marshal(person)
	fmt.Println(string(jsondata))
}

輸出結果

> go run example1.go
{1 Daniel}
{"id":1,"Name":"Daniel"}

json Array

json Array 的格式像這樣,就是 Array 裡邊的元素是 json 格式.

[
	{"id" : 1 , "name" : "Daniel"},
	{"id" : 2 , "name" : "Allen"},
	{"id" : 3 , "name" : "Sam"}
]

json Array 的 parser 方式

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Id   int    `json:"id"`
	Name string `json:name`
}

type Persons struct {
	List []Person
}

func main() {
	data := []byte(`[{"id" : 1 , "name" : "Daniel"},{"id" : 2 , "name" : "Allen"},{"id" : 3 , "name" : "Sam"}]`)
	var persons []Person
	json.Unmarshal(data, &persons)
	fmt.Println(persons)
	jsondata, _ := json.Marshal(persons)
	fmt.Println(string(jsondata))
}

也可以改成用 []Person 當作基底型別創造出 Persons 型別使用

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Id   int    `json:"id"`
	Name string `json:name`
}

type Persons []Person

func main() {
	data := []byte(`[{"id" : 1 , "name" : "Daniel"},{"id" : 2 , "name" : "Allen"},{"id" : 3 , "name" : "Sam"}]`)
	var persons Persons
	json.Unmarshal(data, &persons)
	fmt.Println(persons)
	jsondata, _ := json.Marshal(persons)
	fmt.Println(string(jsondata))
}

執行結果

> go run example1.go
[{1 Daniel} {2 Allen} {3 Sam}]
[{"id":1,"Name":"Daniel"},{"id":2,"Name":"Allen"},{"id":3,"Name":"Sam"}]

更複雜的巢狀結構,Students 包含了 string、[]Person 及 Address.

{
	"cId" : "A" , 
	"cType" : "English" , 
	"saddr" : { "hsnId" : "C" , "addr" : "中正路12號" } , 
	"persons" : [
		{"id" : 1 , "name" : "Daniel"},
		{"id" : 2 , "name" : "Allen"},
		{"id" : 3 , "name" : "Sam"}
	]
}

範例程式

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Id   int    `json:"id"`
	Name string `json:name`
}

type Address struct {
	HsnId string `json:"hsnId"`
	Addr  string `json:"addr"`
}

type Students struct {
	ClassId   string   `json:"cId"`
	ClassType string   `json:"cType"`
	List      []Person `json:"persons"`
	Addr      Address  `json:"saddr"`
}

func main() {
	data := []byte(`{"cId" : "A" , "cType" : "English" , "saddr" : { "hsnId" : "C" , "addr" : "中正路12號" } , "persons" : [{"id" : 1 , "name" : "Daniel"},{"id" : 2 , "name" : "Allen"},{"id" : 3 , "name" : "Sam"}]}`)
	var students Students
	json.Unmarshal(data, &students)
	fmt.Println(students)
	for _, p := range students.List {
		fmt.Println(p)
	}
	jsondata, _ := json.Marshal(students)
	fmt.Println(string(jsondata))
}

執行結果

> go run example1.go
{A English [{1 Daniel} {2 Allen} {3 Sam}] {C 中正路12號}}
{1 Daniel}
{2 Allen}
{3 Sam}
{"cId":"A","cType":"English","persons":[{"id":1,"Name":"Daniel"},{"id":2,"Name":"Allen"},{"id":3,"Name":"Sam"}],"saddr":{"hsnId":"C","addr":"中正路12號"}}

不使用 struct 的方式去 parser,使用 map 的方式

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	data := []byte(`{"cId" : "A" , "cType" : "English" , "saddr" : { "hsnId" : "C" , "addr" : "中正路12號" } , "persons" : [{"id" : 1 , "name" : "Daniel"},{"id" : 2 , "name" : "Allen"},{"id" : 3 , "name" : "Sam"}]}`)
	var jsonObj map[string]interface{}
	json.Unmarshal([]byte(data), &jsonObj)
	classID := jsonObj["cId"].(string)
	classType := jsonObj["cType"].(string)

	fmt.Println(classID)
	fmt.Println(classType)

	studentsAddr := jsonObj["saddr"].(map[string]interface{})
	hsnID := studentsAddr["hsnId"].(string)
	addr := studentsAddr["addr"].(string)

	fmt.Println(hsnID)
	fmt.Println(addr)

	persons := jsonObj["persons"].([]interface{})
	for _, p := range persons {
		person := p.(map[string]interface{})
		id := int(person["id"].(float64))
		name := person["name"].(string)
		fmt.Printf("%d , %v \n", id, name)
	}
}

輸出結果

> go run example1.go
A
English
C
中正路12號
1 , Daniel
2 , Allen
3 , Sam

上一篇
Go day 24 (testing)
下一篇
Go day 26 (mongodb)
系列文
學習Go30

尚未有邦友留言

立即登入留言