go原生json(一)

go原生json(一)

处理json数据是绝大多数程序员都熟悉的操作,很多语言都提供了对json数据的转化和从json中恢复对象的功能(即序列化和反序列化)。go语言也不例外,go原生的encoding/json库提供了相当强大的功能,可以非常简单地处理序列化和反序列化。

1 json.Marshal()和json.Unmarshal()函数

使用encoding/json库的Marshal()Unmarshal()函数能够轻松地将go的结构体序列化成二进制格式的json数据,以及把json格式的数据反序列化到结构体中。

示例1:

package main

import (
 "encoding/json"
 "fmt"
)

// 结构体的成员变量必须以大写字母开头才能被序列化成json
type Employee struct {
 ID    int
 Name  string
 Email string
}

func main() {
 employee1 := Employee{1001, "Bob", "xyz@abc.com"}

 // 序列化
 jsonData, err := json.Marshal(employee1)
 if err != nil {
 fmt.Println("serializes failed.")
 }
 // 默认序列化后是二进制的字节数组
 fmt.Println(jsonData)
 // output: [123 34 73 68 34 58 49 48 48 49 44 34 78 97 109 101 34 58 34 66 111 98 34 44 34 69 109 97 105 108 34 58 34 120 121 122 64 97 98 99 46 99 111 109 34 125]

 fmt.Println(string(jsonData))
 // output: {"ID":1001,"Name":"Bob","Email":"xyz@abc.com"}

 // 反序列化
 var employee2 Employee
 err = json.Unmarshal(jsonData, &employee2)
 if err != nil {
 fmt.Println("deserializes failed.")
 }
 fmt.Println(employee2)
 // output: {1001 Bob xyz@abc.com}
}

使用前需通过import关键字导入encoding/json库,使用json.Marshal()序列化结构体时需要注意,结构体的成员变量必须是以大写字母开头(go用首字母大小写表示函数、变量、结构体等是公有的还是私有的,如果是首字母小写的变量,即为私有变量,不能被序列化到json数据中),并且函数返回的是一个字节数组。

使用json.Unmarshal()函数反序列化时,要注意传入的json数据是字节数组,并且传入json对应的结构体类型的变量,把json数据赋值给该结构体变量。

2 json.MarshalIndent()函数

在第一个示例中,使用string()函数把序列化后的字节数组转换成string,打印输出的结果是一行。示例中的结构体成员域比较简单,所以显示在一行中看起来没有太糟糕,但是当序列化一个较复杂的结构体并输出后,这样看是非常不方便的,于是encoding/json库提供了一个MarshalIndent()函数来格式化输出。

jsonData, err := json.MarshalIndent(employee1, "", "  ")

使用这行代码替换示例1中的json.Marshal(),第二个参数表示前缀,暂时不需要,提供一个零值,第三个参数为缩进,这里用两个空格进行缩进,这样得到的json数据就非常清晰了。


图片.png

3 对未知结构的json数据进行反序列化

示例1中对Employee结构体类型的数据进行反序列化,我们需要先构造一个对应的结构体变量,用于接收json数据的每一个字段值。

实际场景中,我们可能会遇到一些未知结构或不确定结构的json数据,但是又需要该数据中的某些字段。json.Unmarshal()函数的第二个参数实际上是一个KV格式的数据类型(map[string]interface{})。当我们不清楚json数据的结构时,直接声明一个map[string]interface{}类型的变量,可以接收任意结构的json数据。

示例2:

package main

import (
 "encoding/json"
 "fmt"
)

var employee = `{
 "ID": 1001,
 "Name": "Bob",
 "Age":"28",
 "Email": "xyz@abc.com",
 "Position":"programmer"
}`

func main() {
 // 对未知结构的json数据进行反序列化
 var m map[string]interface{}
 err := json.Unmarshal([]byte(employee), &m)
 if err != nil {
 fmt.Println("deserializes failed.")
 }
 fmt.Println(m)
 // output: map[Age:28 Email:xyz@abc.com ID:1001 Name:Bob Position:programmer]
}

上述示例有一个json数据,不同于示例1,该结构多了员工的年龄和职位,显然不能使用Employee结构体接收这个json。可以使用map[string]interface{}类型的变量获取json的字段值。由于是map类型的KV(hash),字段的顺序可能会发生变化。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容

  • Go中的标准库encoding/json提供JSON格式的序列化和反序列化功能. 序列化struct为JSON P...
    asdzxc阅读 279评论 0 0
  • JSON(JavaScript Object Notation,JS对象标记)是一种比XML更为轻量的【数据交换格...
    JunChow520阅读 888评论 0 1
  • 参考:https://sanyuesha.com/2018/05/07/go-json/[https://sany...
    天空蓝雨阅读 4,215评论 0 3
  • 很多程序都需要处理或者发布数据,不管这个程序是要使用数据库,进行网络调用,还是与分布式系统打交道。如果程序需要处理...
    Go语言由浅入深阅读 1,223评论 0 1
  • 个人觉得,有谷歌翻译,百度翻译。加上自己的理解。自个看看官方文档也还不错。下面98%是谷歌翻译跟百度翻译的。剩余2...
    言十年阅读 1,873评论 0 2