您的位置:首页 > Web前端 > JavaScript

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

2016-02-22 23:37 1026 查看

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
将会为
nil
b
将会是一个包含 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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  go json