encoding/json – Go语言的JSON编码与解码库

encoding/json – Go语言的JSON编码与解码库

JSON(JavaScript Object Notation)是现代应用中最常用的数据交换格式之一。Go语言标准库中的encoding/json包提供了完整的JSON编码和解码功能,让我们能够方便地在Go数据结构与JSON格式之间进行转换。

JSON编码(序列化)

将Go数据结构转换为JSON字符串的过程称为编码或序列化。json.Marshal()函数是实现这一功能的核心方法。

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
    Addr string `json:"addr,omitempty"`
}

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}
}

结构体标签

结构体字段可以添加json标签来控制编码行为:

  • json:"fieldName" – 指定JSON字段名称
  • omitempty – 如果字段为零值,则省略该字段
  • -" – 完全忽略该字段

JSON解码(反序列化)

将JSON字符串转换回Go数据结构的过程称为解码或反序列化。json.Unmarshal()函数用于实现这一功能。

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 Addr:}

处理复杂JSON

嵌套结构体

type Address struct {
    City    string `json:"city"`
    Country string `json:"country"`
}

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

动态JSON字段(interface{})

当JSON结构不确定时,可以使用interface{}

var data map[string]interface{}
jsonStr := `{"name":"Charlie","age":40,"skills":["Go","Python"]}`

err := json.Unmarshal([]byte(jsonStr), &data)
if err != nil {
    log.Fatal(err)
}

fmt.Println(data["skills"].([]interface{})[0]) // 输出: Go

流式处理

对于大型JSON数据,可以使用json.Decoderjson.Encoder进行流式处理:

// 从标准输入读取并解码JSON
var p Person
decoder := json.NewDecoder(os.Stdin)
err := decoder.Decode(&p)

// 编码并写入标准输出
encoder := json.NewEncoder(os.Stdout)
encoder.Encode(p)

自定义编解码

通过实现json.Marshalerjson.Unmarshaler接口,可以自定义类型的编解码行为:

type CustomTime struct {
    time.Time
}

func (ct *CustomTime) MarshalJSON() ([]byte, error) {
    return []byte(`"` + ct.Format("2006-01-02") + `"`), nil
}

func (ct *CustomTime) UnmarshalJSON(b []byte) error {
    s := strings.Trim(string(b), `"`)
    t, err := time.Parse("2006-01-02", s)
    if err != nil {
        return err
    }
    ct.Time = t
    return nil
}

性能优化

  1. 预分配缓冲区:对于大型JSON,使用bytes.Buffer预分配内存
  2. 重用解码器:避免频繁创建json.Decoder实例
  3. 使用json.RawMessage延迟解析部分JSON

常见陷阱

  1. 未导出字段(小写开头)默认不会被编码
  2. 循环引用会导致编码失败
  3. 数字解码为float64类型
  4. JSON中的null被解码为Go的nil

总结

encoding/json包提供了强大而灵活的JSON处理能力,是Go语言中处理JSON数据的首选方案。通过结构体标签、自定义编解码和流式处理等高级特性,我们可以高效地处理各种JSON数据场景。

下一期我们将深入探讨net/http包 – Go语言强大的HTTP服务器和客户端实现,包括HTTP服务器搭建、路由处理、中间件机制等核心功能。

暂无评论

发送评论 编辑评论


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