encoding/json 库深度解析

encoding/json 库深度解析

1. 简介

标准库中的encoding/json包提供了对JSON数据的编码和解码功能,是Go语言中处理JSON数据最常用的工具之一。它可以实现Go数据结构和JSON之间的相互转换,支持基本的序列化和反序列化操作。

2. 核心功能

2.1 JSON编码(Marshal)

将Go数据结构转换为JSON字符串:

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    p := Person{Name: "Alice", Age: 25}
    jsonData, err := json.Marshal(p)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(jsonData)) // 输出: {"name":"Alice","age":25}
}

2.2 JSON解码(Unmarshal)

将JSON字符串解析为Go数据结构:

jsonStr := `{"name":"Bob","age":30}`
var p Person
err := json.Unmarshal([]byte(jsonStr), &p)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("%+v\n", p) // 输出: {Name:Bob Age:30}

2.3 流式处理(Encoder/Decoder)

对于大文件或网络流的处理,可以使用流式API:

// 流式编码
func encodeToStream(w io.Writer, data interface{}) error {
    enc := json.NewEncoder(w)
    return enc.Encode(data)
}

// 流式解码
func decodeFromStream(r io.Reader, v interface{}) error {
    dec := json.NewDecoder(r)
    return dec.Decode(v)
}

3. 高级特性

3.1 结构体标签控制

通过结构体标签可以控制JSON编码/解码的行为:

type User struct {
    ID       int      `json:"id,omitempty"`
    Username string   `json:"username"`
    Password string   `json:"-"`               // 忽略该字段
    Roles    []string `json:"roles,omitempty"` // 如果为空则忽略
}

3.2 自定义Marshal/Unmarshal

实现json.Marshalerjson.Unmarshaler接口可以进行自定义序列化:

type CustomTime time.Time

func (ct CustomTime) MarshalJSON() ([]byte, error) {
    t := time.Time(ct)
    return []byte(fmt.Sprintf(`"%s"`, t.Format("2006-01-02"))), nil
}

func (ct *CustomTime) UnmarshalJSON(data []byte) error {
    // 自定义解析逻辑
}

3.3 处理未知字段

使用json.RawMessage延迟解析或在Unmarshal时使用map[string]interface{}:

var data map[string]interface{}
json.Unmarshal(jsonData, &data)

// 或者
type Message struct {
    Body    json.RawMessage // 延迟解析
    Extras map[string]interface{} // 存储未知字段
}

4. 性能优化

4.1 复用Encoder/Decoder

对于高频使用的场景,可以复用Encoder和Decoder:

var enc = json.NewEncoder(os.Stdout)
for _, v := range values {
    if err := enc.Encode(v); err != nil {
        log.Println(err)
    }
}

4.2 使用jsoniter等第三方库

对于极致性能要求,可以考虑使用jsoniter等第三方库:

import jsoniter "github.com/json-iterator/go"

var json = jsoniter.ConfigCompatibleWithStandardLibrary

5. 常见陷阱

5.1 循环引用

处理包含循环引用的数据结构时需要小心:

type Node struct {
    Value    int
    Children []*Node
}

// 解决方案: 使用ID引用或实现自定义序列化

5.2 NaN/Infinity处理

JSON规范不支持NaN和Infinity,需要特殊处理:

func (f Float64) MarshalJSON() ([]byte, error) {
    if math.IsNaN(float64(f)) {
        return []byte(`"NaN"`), nil
    }
    // ...
}

5.3 指针字段

指针字段为nil时会被编码为null,而非零值:

type Container struct {
    Value *int `json:"value"`
}

6. 总结

encoding/json是Go语言中处理JSON数据的核心库,提供了丰富的功能和灵活的配置选项。掌握它的使用技巧可以有效提升开发效率和程序性能。


文末预告:下一期我们将深入学习net/http库,详细介绍如何使用Go语言构建HTTP服务器和客户端。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇