在 Go 的标准库中,encoding/json
包提供了多种函数用于处理 JSON 数据。以下是一些常用的函数和它们的用途:
1. json.Marshal
-
用途: 将 Go 值编码为 JSON 格式的字节切片。
-
签名 :
gofunc Marshal(v interface{}) ([]byte, error)
-
参数 :
v
是要编码的 Go 值,通常是一个结构体、数组、切片、映射等。 -
返回值: 返回编码后的字节切片和可能出现的错误。
示例:
go
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
p := Person{Name: "John", Age: 30}
data, err := json.Marshal(p)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(data)) // 输出: {"name":"John","age":30}
}
2. json.Unmarshal
-
用途: 将 JSON 数据解码为 Go 类型。
-
签名 :
gofunc Unmarshal(data []byte, v interface{}) error
-
参数 :
data
是要解码的 JSON 数据的字节切片。v
是目标 Go 类型的指针,通常是一个结构体或切片。
-
返回值: 返回解码过程中可能发生的错误。
示例:
go
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
data := []byte(`{"name":"Alice","age":25}`)
var p Person
err := json.Unmarshal(data, &p)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(p) // 输出: {Alice 25}
}
3. json.NewEncoder
-
用途 : 返回一个新的
json.Encoder
,可以用于将 Go 值直接编码为 JSON,并写入到io.Writer
。 -
签名 :
gofunc NewEncoder(w io.Writer) *Encoder
-
参数 :
w
是一个io.Writer
,可以是文件、网络连接或标准输出等。 -
返回值 : 返回一个新的
json.Encoder
。
示例:
go
package main
import (
"encoding/json"
"fmt"
"os"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
p := Person{Name: "Bob", Age: 40}
encoder := json.NewEncoder(os.Stdout)
err := encoder.Encode(p)
if err != nil {
fmt.Println("Error:", err)
}
}
4. json.NewDecoder
-
用途 : 返回一个新的
json.Decoder
,可以用于从io.Reader
中读取 JSON 数据并解码为 Go 值。 -
签名 :
gofunc NewDecoder(r io.Reader) *Decoder
-
参数 :
r
是一个io.Reader
,可以是文件、网络连接或标准输入等。 -
返回值 : 返回一个新的
json.Decoder
。
示例:
go
package main
import (
"encoding/json"
"fmt"
"strings"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
data := `{"name":"Eve","age":22}`
decoder := json.NewDecoder(strings.NewReader(data))
var p Person
err := decoder.Decode(&p)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(p) // 输出: {Eve 22}
}
5. json.Indent
-
用途: 格式化 JSON 字节切片,使其更具可读性(添加缩进)。
-
签名 :
gofunc Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
-
参数 :
dst
是输出的缓冲区(通常是*bytes.Buffer
)。src
是待格式化的 JSON 数据。prefix
是每行的前缀。indent
是每一层嵌套的缩进字符。
-
返回值: 返回格式化过程中可能发生的错误。
示例:
go
package main
import (
"bytes"
"encoding/json"
"fmt"
)
func main() {
data := []byte(`{"name":"Charlie","age":30}`)
var out bytes.Buffer
err := json.Indent(&out, data, "", " ")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(out.String())
}
输出:
json
{
"name": "Charlie",
"age": 30
}
6. json.RawMessage
-
用途: 用于延迟 JSON 解码,或在不解码的情况下持有原始的 JSON 数据。
-
类型 :
gotype RawMessage []byte
-
用法 : 通过
RawMessage
类型,你可以将 JSON 数据存储为原始的字节切片,稍后再解码或直接传递给其他函数。
示例:
go
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Details json.RawMessage `json:"details"`
}
func main() {
data := []byte(`{"name":"John","age":25,"details":{"city":"New York"}}`)
var p Person
err := json.Unmarshal(data, &p)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Name:", p.Name) // 输出: Name: John
fmt.Println("Age:", p.Age) // 输出: Age: 25
fmt.Println("Details:", string(p.Details)) // 输出: Details: {"city":"New York"}
// 你可以稍后再处理 "details" 字段
var details map[string]string
err = json.Unmarshal(p.Details, &details)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("City:", details["city"]) // 输出: City: New York
}
总结
json.Marshal
: 将 Go 值编码为 JSON。json.Unmarshal
: 将 JSON 解码为 Go 值。json.NewEncoder
: 创建一个编码器,直接将 Go 值写入io.Writer
。json.NewDecoder
: 创建一个解码器,从io.Reader
读取并解码 JSON。json.Indent
: 对 JSON 数据进行格式化,添加缩进。json.RawMessage
: 用于存储和处理未解码的 JSON 数据。
这些函数是 Go 处理 JSON 数据时最常用的功能,涵盖了编码、解码、格式化以及延迟解码等常见需求。