go复合数据类型struct和json互相转换

1,564 阅读2分钟

将一个Go语言中结构体slice转为JSON的过程叫编组(marshaling),通过调用json.Marshal函数完成编码,编码的逆操作是解码,对应将JSON数据解码为Go语言的数据结构,Go语言中一般叫unmarshaling,通过调用 json.Unmarshaling函数完成解码;

package main

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

type Article struct { 
	ID        uint
	Title     string
	Filename  string `json:"filename,omitempty"`
	AuthorId  uint   `json:"authorId"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

func main() {
	var articles = []Article{
		{Title: "文章标题1", Filename: "article.text", AuthorId: 123},
		{Title: "文章标题1",   AuthorId: 123},
	}

	data, _ := json.Marshal(articles)

	fmt.Printf("%s\n", data)
}

输入出结果如下:

[{"ID":0,"Title":"文章标题1","filename":"article.text","authorId":123},{"ID":0,"Title":"文章标题1","authorId":123}]

这种紧凑的表示形式虽然包含了全部的信息,但是很难阅读。为了生成便于阅读的格式,使用 json.MarshalIndent函数将产生整齐缩进的输出。该函数有两个额外的字符串参数用于表示每一行输出 的前缀和每一个层级的缩进:

	//data, _ := json.Marshal(articles)
	data, _ := json.MarshalIndent(articles, "", "    ")

替换后输出结果如下:

[
    {
        "ID": 0,
        "Title": "文章标题1",
        "filename": "article.text",
        "authorId": 123
    },
    {
        "ID": 0,
        "Title": "文章标题1",
        "authorId": 123
    }
]

Article结构体声明中,FilenameAuthorId成员后面的字符串面值是结构体成员Tag;结构体的成员Tag可以是任意的字符串面值,但是通常是一系列用空格分隔的key:"value"键值对序列; 因为值中含义双引号字符,因此成员Tag一般用原生字符串面值的形式书写;

成员Tag中json开头键名对应的值用于控制encoding/json包的编码和解码的行为,并且encoding/...下面其它的包也遵循这个约定。成员Tag 中json对应值的第一部分用于指定JSON对象的名字,如上:FilenameAuthorId字段Tag中第一部分指定了JSON对象的名字;Tag还带了一个额外的omitempty选项,表示当Go语言结构体成员为空或 零值时不生成JSON对象

下面的代码将JSON格式的数据解码为一个结构体

	var articles2 []Article
	var err error
 	err = json.Unmarshal(data, &articles2)
	fmt.Println(articles2)  // [{0 文章标题1 article.text 123} {0 文章标题1  123}]

json.Unmarshal接收两个参数,分别是[]byte字节slice 和 interface{}类型,并返回 errort类型的值;