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 main
import (
"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]int
json.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 []Product
json.Unmarshal(bytes, &json2)
fmt.Println("复杂对象 json to go: ", json2)
}
}
// compact 测试
func jsonTest3() {
fmt.Println("jsonTest3 begin")
var buf bytes.Buffer
jsonBytes := []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()
}