在 GO 编程语言中处理 JSON 数据

Li_Jun__ · · 2684 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1. 简介

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。其语法上类似于 JavaScript 的对象和列表。最常用于 web 后端之间的通信和在浏览器中运行 JavaScript 程序,但是其它地方也大量使用。其主页:json.org,提供了一个非常清晰和简明定义的标准。
使用 json 包 可以很容易的在 GO 程序中读写 JSON 数据。

2. 编码

使用 Marshal 函数生成 JSON 数据。

func Marshal(v interface{}) ([]byte, error)

给定 GO 数据的结构体:Message

type Message struct {
    Name string
    Body string
    Time int64
}

然后获取 Message 的一个实例。

m := Message{"Alice", "Hello", 1294706395881547000}

使用 json.Marshal 获得一个 JSON 格式的 m。

b, err := json.Marshal(m)

如果一切顺利,err 将会为 nilb 将会是一个包含 JSON 数据的 []byte

b == []byte(`{"Name":"Alice","Body":"Hello","Time":1294706395881547000}`)

只有当数据结构体能被表示成合法的 JSON 时,才会被编码。

  • JSON 对象只支持 strings 类型作为键名;必须使用 map[string]T来编码成 Go map 类型(其中 T 是任意一种 json 包支持的 Go 类型)。
  • Channel,complex 和函数类型不能被编码。
  • 不支持循环的数据结构,将会导致 Marshal 进入死循环。
  • 指针将被编码成它们指向的值(或’null’,如果指针是零)。

json包只访问公开字段的结构体类型(以大写字母开头的那些),因此只有公开字段的结构体会出现在 JSON 输出中。

示例代码

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

func main() {
    type ColorGroup struct {
        ID     int
        Name   string
        Colors []string
    }
    group := ColorGroup{
        ID:     1,
        Name:   "Reds",
        Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
    }
    b, err := json.Marshal(group)
    if err != nil {
        fmt.Println("error:", err)
    }
    os.Stdout.Write(b)
}

3. 解码

使用 Unmarshal 函数解析 JSON 数据。

func Unmarshal(data []byte, v interface{}) error

首先必须创建一个存放解析数据的地方。

var m Message

然后调用 json.Unmarshal,传入一个包含 JSON 数据的 []byte 和一个指针 m。

err := json.Unmarshal(b, &m)

如果 b 包含适合 m 的有效的 JSON 数据,那么调用 err 将会是nil,然后数据将会从 b 保存到结构体 m 中,就像赋值:

m = Message{
    Name: "Alice",
    Body: "Hello",
    Time: 1294706395881547000,
}

使用 Unmarshal 时,如何定义用于保存解码数据的字段?对于给定的键 "Foo"Unmarshal 将会浏览目标结构体来查找相应字段。(按优先顺序排列)

  • 一个标签为 "Foo" 的公开字段(更多结构体标签查看 Go spec),
  • 一个名称为 "Foo" 的公开字段,或
  • 一个名称为 "FOO""FoO" 或一些其它的不区分大小写匹配 "Foo" 的公开字段。

如果 JSON 数据的结构体与 Go 类型不完全匹配?

b := []byte(`{"Name":"Bob","Food":"Pickle"}`)
var m Message
err := json.Unmarshal(b, &m)

Unmarshal 只解析目标类型中定义的字段。在这个例子中,只有 m 的 Name 字段会被解析,而 Food 字段将被忽略。当只希望从大的 JSON 数据中选择少量特定字段时,该行为非常实用。这也意味着任何目标结构体的私有字段将不受 Unmarshal 影响。

示例代码

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var jsonBlob = []byte(`[
        {"Name": "Platypus", "Order": "Monotremata"},
        {"Name": "Quoll",    "Order": "Dasyuromorphia"}
    ]`)
    type Animal struct {
        Name  string
        Order string
    }
    var animals []Animal
    err := json.Unmarshal(jsonBlob, &animals)
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Printf("%+v", animals)
}

4. 笔记

  • 自定义输出的 JSON 数据的键名,在字段类型后使用反单引号 json:" "
    type Animal struct {
        Name  string `json:"name"`
        Order string
    }
  • 如果双引号中间是 - ,该字段将不会输出:
    type Animal struct {
        Name  string `json:"-"`
        Order string
    }

参考资料
Go 博客:http://blog.golang.org/json-and-go
Go 编程语言 json 包:https://golang.org/pkg/encoding/json/
rgyq 博客:http://rgyq.blog.163.com/blog/static/316125382013934153244/


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:Li_Jun__

查看原文:在 GO 编程语言中处理 JSON 数据

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2684 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传