作者:尹正傑
版權宣告:原創作品,謝絕轉載!否則將追究法律責任。
目錄
- 一.json概述
- 二.結構體的序列化JSON格式
- 三.結構體的反序列化JSON格式
- 四.結構體標籤(tag)
- 1 結構體標籤(tag)概述
- 2 結構體標籤(tag)案例
- 五.鏈式程式設計
一.json概述
JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。易於人閱讀和編寫。同時也易於機器解析和生成。
JSON鍵值對是用來儲存JS物件的一種方式,鍵/值對組合中的鍵名寫在前面並用雙引號""包裹,使用冒號:分隔,然後緊接著值;多個鍵值之間使用英文,分隔。
二.結構體的序列化JSON格式
package main
import (
"encoding/json"
"fmt"
)
// Book 書籍結構體
type Book struct {
ID int
Name string
}
// Auther 作者
type Auther struct {
Auther string
Alias string
Books []*Book
}
func main() {
// 定義作者
auther := &Auther{
Auther: "楊振東",
Alias: "辰東",
Books: make([]*Book, 0, 200),
}
// 定義書籍
b1 := &Book{1, "《完美世界》"}
b2 := &Book{2, "《遮天》"}
b3 := &Book{3, "《聖墟》"}
// 將資料加入到作者的書籍切片中
auther.Books = append(auther.Books, b1)
auther.Books = append(auther.Books, b2)
auther.Books = append(auther.Books, b3)
//JSON序列化:結構體-->JSON格式的字串
data, err := json.Marshal(auther)
if err != nil {
fmt.Printf("%v序列化JSON格式失敗\n", auther)
return
}
fmt.Printf("JSON格式轉換前: %#v\n", auther)
fmt.Printf("JSON格式轉換後: %s\n", data)
}
三.結構體的反序列化JSON格式
package main
import (
"encoding/json"
"fmt"
)
// Book 書籍結構體
type Book struct {
ID int
Name string
}
// Auther 作者
type Auther struct {
Auther string
Alias string
Books []*Book
}
func main() {
str := `{"Auther":"楊振東","Alias":"辰東","Books":[{"ID":1,"Name":"《完美世界》"},{"ID":2,"Name":"《遮天》"},{"ID":3,"Name":"《聖墟》"}]}`
auther := &Auther{}
//JSON反序列化:將JSON格式的字串轉換為結構體
err := json.Unmarshal([]byte(str), auther)
if err != nil {
fmt.Printf("JSON反序列化為結構體失敗: err =%v\n", err)
return
}
fmt.Printf("auther = %#v\n", auther)
fmt.Printf("'%s'筆名是'%s',代表作有:%q\n", auther.Auther, auther.Alias, auther.Books)
}
四.結構體標籤(tag)
1 結構體標籤(tag)概述
Tag是結構體的元資訊,可以在執行的時候透過反射的機制讀取出來。
Tag在結構體欄位的後方定義,由一對反引號包裹起來,具體的格式如下:
`key1:"value1" key2:"value2"`
結構體tag由一個或多個鍵值對組成。鍵與值使用冒號分隔,值用雙引號括起來。同一個結構體欄位可以設定多個鍵值對tag,不同的鍵值對之間使用空格分隔。
注意事項:
為結構體編寫Tag時,必須嚴格遵守鍵值對的規則。結構體標籤的解析程式碼的容錯能力很差,一旦格式寫錯,編譯和執行時都不會提示任何錯誤,透過反射也無法正確取值。例如不要在key和value之間新增空格。
2 結構體標籤(tag)案例
package main
import (
"encoding/json"
"fmt"
)
type Teacher struct {
// 透過指定tag實現json序列化該欄位時的key
Name string `json:"name"`
Hobby []string `json:"hobby"`
// json序列化是預設使用欄位名作為key
Blog string
// 小寫字母屬於私有屬性,不能被json包訪問
age int
skill string `json:"skill"`
}
func main() {
hobby := []string{"K8S", "打遊戲", "旅遊"}
t1 := &Teacher{
Name: "周敏",
age: 18,
Hobby: hobby,
skill: "K8S",
Blog: "https://www.cnblogs.com/yinzhengjie",
}
fmt.Printf("結構體源資料 : %#v\n", t1)
// JSON序列化:結構體-->JSON格式的字串
data, err := json.Marshal(t1)
if err != nil {
fmt.Println("json marshal failed!")
return
}
fmt.Printf("JSON資料: %s\n", data)
}
五.鏈式程式設計
package main
import (
"encoding/json"
"fmt"
"os"
)
/*
鏈式操作:
這種連續使用"."的方式調方法我們稱之為"鏈式操作"。
鏈式原理:
每一次執行完方法之後返回操作的物件本身。
*/
type Teacher struct {
Name string `json:"name"`
Age uint8 `json:"age"`
Blog string `json:"blog"`
}
func (t Teacher) Learn() Teacher {
fmt.Printf("%s熱愛學習\n", t.Name)
return t
}
func (t Teacher) WriteBolog() Teacher {
fmt.Printf("%s熱愛寫部落格,部落格地址: %s\n", t.Name, t.Blog)
return t
}
func (t Teacher) Marshal(filePath string) Teacher {
// 以只寫的模式開啟檔案
file, _ := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
defer file.Close()
// JSON序列化:結構體-->JSON格式的字串
data, _ := json.Marshal(t)
fmt.Printf("JSON資料: %s\n", data)
// 寫入位元組切片資料
file.Write([]byte(data))
return t
}
func main() {
t1 := Teacher{
Name: "JasonYin",
Age: 20,
Blog: "https://www.cnblogs.com/yinzhengjie",
}
t1.Learn().WriteBolog().Marshal("blog.txt")
}