iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

還喝不 go系列 第 18

[13th][Day18] Unmarshal

有句話說,沒用過 unmarshal 就等於沒寫過 go

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

Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.

簡單來說,收到 data ,用 unmarshal 的方式解到 v 所指向的值
data 須為 []byte 型態 ,v 通常會用 &x 這種寫法

本身用過的 unmarshal 方式有兩種
1.指定 struct 的方式
2.用 map[string]interface{} 的方式

先定義一個天線寶寶 struct

type Teletubbies struct {
	Name  string
	Color string
}

準備一個 要用來解開的string

sliceString := `[{"Name": "Tinky Winky", "Color": "Purple"},{"Name": "Dipsy",    "Color": "Green"}]`

注意~~這是一個 slice 而非 json 格式哦

用 struct 的方式解開他

x1 := []Teletubbies{}
	err := json.Unmarshal([]byte(sliceString), &x1)
	if err != nil {
		fmt.Println(err)
		return
	}

unmarshal 非常容易發生錯誤,請做好錯誤處理

也可以用 map[string]interface 的方試是看看

	mapInSlice := []map[string]interface{}{}
	err = json.Unmarshal([]byte(sliceString), &mapInSlice)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(mapInSlice)

接下來我們就要解看看 json 格式囉

mapString := `{"kk1":{"Name": "Tinky Winky", "Color": "Purple"},"kk2":{"Name": "Dipsy",    "Color": "Green"},"kk3":{"Name": "Laa-Laa"}}`

layer1 := make(map[string]interface{})
	err = json.Unmarshal([]byte(mapString), &layer1)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(layer1)
	fmt.Println(layer1["kk1"])

此時的 layer1["kk1"]仍然是一個 map ,但型態為 interface{}
可以用 assertion 來斷言

if _, ok := layer1["kk1"].(map[string]interface{}); ok {
		layer2 := layer1["kk1"].(map[string]interface{})
		fmt.Println(layer2["Name"])
	}

上面說到 unmarshal 很容易壞掉,assertion 也是很容易壞掉的,做好錯誤處理 or 更多的預防可以減少服務爆炸的風險。


上一篇
[13th][Day17] tamplete range
下一篇
[13th][Day19] http request header(上)
系列文
還喝不 go20

尚未有邦友留言

立即登入留言