json 與 encoding/json
JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,它基于 ECMAScript(歐洲計算機協會制定的js規范)的一個子集,采用完全獨立于語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成為理想的數據交換語言。json具有以下特點:
- 易讀性:JSON 格式的數據易于閱讀和編寫,同時也易于機器解析和生成。
- 輕量級:JSON 的數據格式非常簡單,使得數據的傳輸和存儲更加高效。
- 跨語言:JSON 是一種中立的數據格式,可以被多種編程語言所支持。
encoding/json 是 Go 語言標準庫中的一個重要包,它提供了對 JSON 數據格式的編碼(序列化)和解碼(反序列化)支持;它使得 Go 語言能夠輕松、高效地處理 JSON 數據,使得開發者能夠方便地將 Go 數據結構序列化為 JSON 格式的字符串,或者將 JSON 字符串反序列化為 Go 的數據結構。
說明
提供的方法
Compact
func Compact(dst *bytes.Buffer, src []byte) error
作用:Compact函數會將src省略不重要的空格字符后追加到json編碼的src中。
HTMLEscape
func HTMLEscape(dst *bytes.Buffer, src []byte)
作用:在JSON編碼的src中附加<,>,&,U+2028 和 U+2029 字符,字符串字面量更改為 \u003c, \u003e, \u0026, \u2028, \u2029,以便JSON可以安全地嵌入HTML以及script標記中。由于歷史原因,web瀏覽器不支持script標簽內的標準HTML轉義,因此必須使用替代的JSON編碼。
Indent
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
Indent 函數接收一個 JSON 字節切片(通常是通過 Marshal 或 MarshalIndent 函數生成的),以及兩個字符串參數:prefix(前綴)和indext(縮進)字符串。函數返回一個新的字節切片,函數內部會將傳入其中的 JSON 數據重新格式化,為每個 JSON 對象的鍵和字符串值都添加前綴和縮進字符串。
Marshal
func Marshal(v any) ([]byte, error)
Marshal 函數用于將 Go 語言中的數據結構(如結構體、切片、映射等)序列化為 JSON 格式字節切片。函數接收一個 Go 語言的對象(可以是任何可以被編碼為 JSON 的類型)作為參數,返回一個將該對應值用 JSON 表示的字節切片。
Unmarshal
func Unmarshal(data []byte, v any) error
Unmarshal 函數用于將 JSON 格式的數據反序列化為 Go 語言的數據結構(如結構體、切片、映射等)。函數接收一個 JSON 格式的字節切片作為輸入,以及一個指向 Go 語言值的指針作為輸出目標,然后嘗試將 JSON 數據解析并填充到該值中。
Valid
func Valid(data []byte) bool
作用:檢測data是否有效。(這個函數在go1.9才添加)
提供的對象
(提供的這些對象都是比函數更靈活的,但是我目前要快速上手go項目,所以這里沒有仔細了解,暫時空著后續補充)
Decoder
Decoder 類型是一個用于從 I/O 流(如文件、網絡連接等)中讀取和解碼 JSON 數據的解碼器。Decoder 提供了比 Unmarshal 函數更靈活和高效的方式來處理 JSON 數據,特別是當需要從數據流中連續讀取多個 JSON 對象時。
Decoder 類型有一個 Decode 方法,它用于從輸入流中讀取并解碼下一個 JSON 編碼的值。可以將一個指向 Go 語言數據結構的指針作為 Decode 方法的參數,以便將解碼后的數據填充到該結構中。
使用 Decoder 的一個典型場景是處理從網絡連接中接收到的流式 JSON 數據,或者從文件中讀取包含多個 JSON 對象的數據。
Delim
Encoder
InvalidUTF8Error
InvalidUnmarshalError
Marshaler
MarshalerError
Number
RawMessage
SyntaxError
Token
UnmarshalerFieldError
UnmarshalerTypeError
Unmarshaler
UnsupportedTypeError
UnsupportedValueError
encoding/json 使用示例
package mainimport ("bytes""encoding/json""fmt"
)// 簡單json對象轉換測試
func jsonTest1() {fmt.Println("jsonTest1 begin")json1 := map[string]int{"cpp": 10,"js": 8,"go": 10,}bytes, _ := json.Marshal(json1)fmt.Println("基礎版go to json: ", string(bytes))if json.Valid(bytes) {var json2 map[string]intjson.Unmarshal(bytes, &json2)fmt.Println("基礎版json to go: ", json2)}
}// 復雜對象轉換測試
type Seller struct {Id int `json:"id"`Name string `json:"name"`CountryCode string `json:"countrycode"`
}
type Product struct {Id int `json:"id"`Name string `json:"name"`Seller Seller `json:"seller"`Price int `json:"price"`
}func jsonTest2() {fmt.Println("jsonTest2 begin")products := []Product{{Id: 50,Name: "Writing Book",Seller: Seller{1, "ABC Company", "US"},Price: 100,},{Id: 51,Name: "Kettle",Seller: Seller{20, "John Store", "DE"},Price: 500,},}bytes, _ := json.Marshal(products)fmt.Println("復雜對象 go to json: ", string(bytes))if json.Valid(bytes) {var json2 []Productjson.Unmarshal(bytes, &json2)fmt.Println("復雜對象 json to go: ", json2)}
}// compact 測試
func jsonTest3() {fmt.Println("jsonTest3 begin")var buf bytes.BufferjsonBytes := []byte(`{"cpp": 10,"js": 8,"go": 10}`)err := json.Compact(&buf, jsonBytes)if err != nil {fmt.Println("compact error : ", err.Error())return}fmt.Println("compact 對象 : ", buf.String())jsonBytes1 := []byte(`{"name":"John", "age":30, "city":"New York"}`)json.Indent(&buf, jsonBytes1, "", " ")fmt.Println("indent 對象 : ", buf.String())
}func main() {jsonTest1()jsonTest2()jsonTest3()
}