Go語言基礎: JSON序列化
阿新 • • 發佈:2022-05-08
JSON 是一種輕量級的資料交換格式。簡潔和清晰的層次結構使得 JSON 成為理想的資料交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提升網路傳輸效率。
首先得熟悉結構體:
package main import "fmt" type Student struct { ID int Gender string Name string Sno string } func main() { var s = Student{ ID: 12, Gender: "男", Name: "李四", Sno: "001", } fmt.Printf("%#v\n", s) }
如上程式碼中定義了一個結構體並且列印
結果: main.Student{ID:12, Gender:"男", Name:"李四", Sno:"001"}
轉化為JSON字串
package main import ( "encoding/json" "fmt" ) type Student struct { ID int Gender string Name string Sno string } func main() { var s = Student{ ID: 12, Gender: "男", Name: "李四", Sno: "001", } // fmt.Printf("%#v\n", s) jsonbByte, _ := json.Marshal(s) jsonStr := string(jsonbByte) fmt.Println(jsonStr) }
json.Marshal返回的是一個Byte型別的切片:
package json // import "encoding/json"
func Marshal(v any) ([]byte, error)
Marshal returns the JSON encoding of v.
然後用string將其轉為字串並列印
那麼JSON字串也可以轉化為結構體
package main import ( "encoding/json" "fmt" ) type Student struct { ID int Gender string Name string Sno string } func main() { // 使用反引號就無須轉義字元 var str = `{"ID":12,"Gender":"男","Name":"李四","Sno":"001"}` var s Student err := json.Unmarshal([]byte(str), &s) if err != nil { fmt.Println(err) } fmt.Printf("%#v", s) }
這裡用到Unmarshal函式來轉換JSON字串
package json // import "encoding/json"
func Unmarshal(data []byte, v any) 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.
程式碼中Unmarshal函式接收兩個引數,第一個是位元組型別的切片,第二個是結構體變數地址。
要注意的是,如果結構體中的某欄位的首字母是小寫的,那麼是不能轉化為JSON字串的,因為是該欄位是私有的。
可以利用結構體標籤來更改JSON字串中的key的形式
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
ID int `json:"id"` // 添加了結構體標籤
Gender string `json:"gender"`
Name string `json:"name"`
Sno string `json:"sno"`
}
func main() {
var s = Student{
ID: 12,
Gender: "男",
Name: "李四",
Sno: "001",
}
// fmt.Printf("%#v\n", s)
jsonbByte, _ := json.Marshal(s)
jsonStr := string(jsonbByte)
fmt.Println(jsonStr)
}
列印結果: {"id":12,"gender":"男","name":"李四","sno":"001"}
顯然這個形式已經與之前的不一樣了,首字母已經被改成了小寫,這就是結構體標籤作用之一。
下面是巢狀結構體的轉化
package main
import (
"encoding/json"
"fmt"
)
// Student 學生結構體
type Student struct {
ID int `json:"id"`
Gender string `json:"gender"`
Name string `json:"name"`
Sno string `json:"sno"`
}
// Class 班級結構體
type Class struct {
Title string
Students []Student
}
func main() {
c := Class{
Title: "001 Class",
Students: make([]Student, 0), // make建立切片
}
for i := 1; i < 10; i++ {
s := Student{
ID: i,
Gender: "男",
Name: fmt.Sprintf("stu_%v", i),
}
c.Students = append(c.Students, s) // 加入切片
}
fmt.Println(c)
strByte, err := json.Marshal(c)
if err != nil {
fmt.Println(err)
} else {
strJson := string(strByte)
fmt.Println(strJson)
}
}
列印結果
{001 Class [{1 男 stu_1 } {2 男 stu_2 } {3 男 stu_3 } {4 男 stu_4 } {5 男 stu_5 } {6 男 stu_6 } {7 男 stu_7 } {8 男 stu_8 } {9 男 stu_9 }]}
{"Title":"001 Class","Students":[{"id":1,"gender":"男","name":"stu_1","sno":""},{"id":2,"gender":"男","name":"stu_2","sno":""},{"id":3,"gender":"男","name":"stu_3","sno":""},{"id":4,"gender":"男","name":_4","sno":""},{"id":5,"gender":"男","name":"stu_5","sno":""},{"id":6,"gender":"男","name":"stu_6","sno":""},{"id":7,"gender":"男","name":"stu_7","sno":""},{"id":8,"gender":"男","name":"stu_8","sno":""},{:9,"gender":"男","name":"stu_9","sno":""}]}
第一行是結構體資訊,其後才是JSON資料
在這個JSON中是資料巢狀存放的,看著比較亂,可以藉助 JSON線上解析 解析該資料
解析結果:
{
"Title":"001 Class",
"Students":[
{
"id":1,
"gender":"男",
"name":"stu_1",
"sno":""
},
{
"id":2,
"gender":"男",
"name":"stu_2",
"sno":""
},
{
"id":3,
"gender":"男",
"name":"stu_3",
"sno":""
},
{
"id":4,
"gender":"男",
"name":"stu_4",
"sno":""
},
{
"id":5,
"gender":"男",
"name":"stu_5",
"sno":""
},
{
"id":6,
"gender":"男",
"name":"stu_6",
"sno":""
},
{
"id":7,
"gender":"男",
"name":"stu_7",
"sno":""
},
{
"id":8,
"gender":"男",
"name":"stu_8",
"sno":""
},
{
"id":9,
"gender":"男",
"name":"stu_9",
"sno":""
}
]
}
那麼又如何將這個字串再轉化回去?
如下所示
package main
import (
"encoding/json"
"fmt"
)
// Student 學生結構體
type Student struct {
ID int `json:"id"`
Gender string `json:"gender"`
Name string `json:"name"`
Sno string `json:"sno"`
}
// Class 班級結構體
type Class struct {
Title string
Students []Student
}
func main() {
str := `{"Title":"001 Class","Students":[{"id":1,"gender":"男","name":"stu_1","sno":""},{"id":2,"gender":"男","name":"stu_2","sno":""},{"id":3,"gender":"男","name":"stu_3","sno":""},{"id":4,"gender":"男","name":"stu_4","sno":""},{"id":5,"gender":"男","name":"stu_5","sno":""},{"id":6,"gender":"男","name":"stu_6","sno":""},{"id":7,"gender":"男","name":"stu_7","sno":""},{"id":8,"gender":"男","name":"stu_8","sno":""},{"id":9,"gender":"男","name":"stu_9","sno":""}]}`
var c = &Class{} // 地址
err := json.Unmarshal([]byte(str), c)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%#v", *c)
}
列印結果
main.Class{Title:"001 Class", Students:[]main.Student{main.Student{ID:1, Gender:"男", Name:"stu_1", Sno:""}, main.Student{ID:2, Gender:"男", Name:"stu_2", Sno:""}, main.Student{ID:3, Gender:"男", Name:"stu_3", Sno:""}, main.Student{ID:4, Gender:"男", Name:"stu_4", Sno:""}, main.Student{ID:5, Gender:"男", Name:"stu_5", Sno:""}, main.Student{ID:6, Gender:"男", Name:"stu_6", Sno:""}, main.Student{ID:7, Gender:"男", Name:"stu_7", Sno:""}, main.Student{ID:8, Gender:"男", Name:"stu_8", Sno:""}, main.Student{ID:9, Gender:"男", Name:"stu_9", Sno:""}}}
JSON序列化就是將結構體轉化為JSON字串
JSON反序列化就是將JSON字串轉化為結構體