分享
  1. 首页
  2. 文章

[Go基础]Json在Go中的使用

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

前言

本文主要根据Go语言Json[1]、官方提供的Json and Go[2]go-and-json[3]整理的。

Marshal

Marshal提供对数据进行Json序列化的功能:

func Marshal(v interface{}) ([]byte, error)
type Message struct {
 Name string
 Body string
 Time int64
}
m := Message{"Alice", "Hello", 1294706395881547000}
b, err := json.Marshal(m)
//result
b == []byte(`{"Name":"Alice","Body":"Hello","Time":1294706395881547000}`)

注意事项:

  • Json对象只支持keystring,序列化Go map类型时必须是map[string]T的形式
  • channel,complexfunction类型无法进行Json序列化
  • 无法序列化存在循环引用的数据,因为Marshal会陷入无限循环
  • 序列化pointer时是它指向的值(空指针序列化后为null)

Unmarshal

func Unmarshal(data []byte, v interface{}) error
var m Message
err := json.Unmarshal(b, &m)
//result:如果b包含符合结构体m的有效json格式,那么b中存储的数据就会保存到m中,比如:
m = Message{
 Name: "Alice",
 Body: "Hello",
 Time: 1294706395881547000,
}

Struct Tags

Golang中构建字段的时候我们可能会在结构体字段名后增加包含在倒引号(backticks)的Tag,如:

type MyStruct struct {
 SomeField string `json:"some_field"`
}
  • Json parser会根据Tag信息去解析字段值
  • Golang中可导出的字段首字母是大写的,这和我们在Json字段名常用小写是相冲突的,通过Tag可以有效解决这个问题
  • Tag信息中加入omitempty关键字后,序列化时自动忽视出现zero-value情形的字段。
    • numberzero-value为0
    • stringzero-valueempty string
    • mapslicepointerzero-valuenil
type MyStruct struct {
 SomeField string `json:"some_field,omitempty"`
}
//在这个例子中,如果some_field为"":
//加上omitempty后,序列化后的Json为{}
//如果不加上omitempty,序列化后的Json为{"some_field": ""}
  • 跳过字段:在Tag中加入"-"
type App struct {
 Id string `json:"id"`
 Password string `json:"-"`
}

嵌套字段

Golang支持struct的嵌套,如:

type App struct {
 Id string `json:"id"`
}
type Org struct {
 Name string `json:"name"`
}
type AppWithOrg struct {
 App
 Org
}

举个栗子,我们现在要将一个[]byte值反序列化为AppWithOrg的结构体:

data := []byte(`
 {
 "id": "k34rAT4",
 "name": "My Awesome Org"
 }
`)
var appWithOrg AppWithOrg
err := json.Unmarshal(data, &appWithOrg)
app := appWithOrg.App
org := appWithOrg.Org
// AND/OR
appId := appWithOrg.Id
orgName := appWithOrg.Name

指针

如果结构体中出现pointer类型,当pointernil时通过dereferenced获取指针对应的值再进行序列化

错误处理

要注意检查MarshalUnmarshal返回的err参数,序列化时出现的错误会比较少见,但当Golang不知道如何将你的数据类型序列化为Json时就会报错(比如你尝试序列化包含nil pointer的数据类型时)。
如果你不想处理Marshal出现的错误时,你可以将Marshal出现的错误转化为panic:

func MustMarshal(data interface{}) []byte {
 out, err := json.Marshal(data)
 if err != nil {
 panic(err)
 }
 return out
}

反序列化任意Json数据

如果你不知道你要解析的Json数据长啥样时,你可以将其反序列化为任意数据类型interface{}

//将Json数据反序列化为任意类型
var parsed interface{}
err := json.Unmarshal(data, &parsed)
//根据parsed数据类型做不同的逻辑处理
switch parsed.(type) {
 case int:
 someGreatIntFunction(parsed.(int))
 case map:
 someMapThing(parsed.(map))
 default:
 panic("JSON type not understood")
}
//另一种类型判定逻辑
intVal, ok := parsed.(int)
if !ok {
 panic("JSON value must be an int")
}

一般情况下,你处理的Json对应的都是一个object,你可以将其反序列化为map[string]interface{}

var parsed map[string]interface{}
data := []byte(`
 {
 "id": "k34rAT4",
 "age": 24
 }
`)
err := json.Unmarshal(data, &parsed)
//直接调用
parsed["id"]
//但使用之前仍然需要格式转换
idString := parsed["id"].(string)

除了object类型外,如果你清楚需要解析的Json格式,可以做如下反序列化:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

Reference

[1]https://golang.org/pkg/encoding/json/#example_Decoder
[2]https://blog.golang.org/json-and-go
[3]https://eager.io/blog/go-and-json/


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

本文来自:简书

感谢作者:TOMOCAT

查看原文:[Go基础]Json在Go中的使用

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

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

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏