文档章节

Go笔记-json

漂泊尘埃
 漂泊尘埃
发布于 2017/02/28 15:01
字数 687
阅读 15
收藏 0

解析json

type Server struct {
	ServerName, ServerIP string
}

type ServerSlice struct {
	Servers []Server
}

func Read() {
	str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}`
	var s ServerSlice
	json.Unmarshal([]byte(str), &s)
	fmt.Println(s)
}

输出:

{[{Shanghai_VPN 127.0.0.1} {Beijing_VPN 127.0.0.2}]}

例如JSON的key是Foo,那么怎么找对应的字段呢?

  1. 首先查找tag含有Foo的可导出的struct字段(首字母大写)
  2. 其次查找字段名是Foo的导出字段
  3. 最后查找类似FOO或者FoO这样的除了首字母之外其他大小写不敏感的导出字段,能够被赋值的字段必须是可导出字段(即首字母大写),同时JSON解析的时候只会解析能找得到的字段,找不到的字段会被忽略
  4. json字符串的name可以被解析到Name字段(没有加tag)

遇到的问题

解析到切片

有一个类型是 []*Tree 的字段,如果需要解析到这个字段的话需要使用 &

json.Unmarshal(bytes, &dirData.root.Children)

Children的类型是

Children []*Tree     `json:"children"`

解析到interface

现在我们假设有如下的JSON数据

b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)

如果在我们不知道他的结构的情况下,我们把他解析到interface{}里面

	b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
	var f interface{}
	json.Unmarshal(b, &f) // 这个时候f里面存储了一个map类型,他们的key是string,值存储在空的interface{}里
	if m, ok := f.(map[string]interface{}); ok {
		for k, v := range m {
			switch vv := v.(type) {
			case string:
				fmt.Println(k, "is string", vv)
			case int:
				fmt.Println(k, "is int", vv)
			case float64:
				fmt.Println(k, "is float64", vv)
			case []interface{}:
				fmt.Println(k, "is an array:")
				for i, u := range vv {
					fmt.Println(i, u)
				}
			default:
				fmt.Println(k, "is of a type I don't know how to handle")
			}
		}
	}

生成JSON

结构体定义如上。

	var s ServerSlice
	s.Servers = append(s.Servers, Server{ServerName: "Shanghai_VPN", ServerIP: "127.0.0.1"})
	s.Servers = append(s.Servers, Server{ServerName: "Beijing_VPN", ServerIP: "127.0.0.2"})
	b, err := json.Marshal(s)
	if err != nil {
		fmt.Println("json err:", err)
	}
	fmt.Println(string(b))

输出:

{"Servers":[{"ServerName":"Shanghai_VPN","ServerIP":"127.0.0.1"},{"ServerName":"Beijing_VPN","ServerIP":"127.0.0.2"}]}

使用json标签

如果将结构体定义成这样:

type Server struct {
	ServerName string `json:"server-name"`
	ServerIP   string `json:"server-ip"`
}

type ServerSlice struct {
	Servers []Server `json:"servers"`
}

输出时:

{"servers":[{"server-name":"Shanghai_VPN","server-ip":"127.0.0.1"},{"server-name":"Beijing_VPN","server-ip":"127.0.0.2"}]}

更多细节参考 json.Marshal

  • 不导出:ID int json:"-"

  • 如果为空,不导出:ServerIP string json:"serverIP,omitempty"

  • 二次JSON编码:

    ServerName  string `json:"serverName"`
    ServerName2 string `json:"serverName2,string"
    

    假如值都是 `Go "1.0" `,输出:

    {"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""}
    

Unmarshal 中没有的字段不会覆盖成默认值

type User struct {
	Name string
	Age  int
}

func main() {
	u := &User{Name: "chen"}
	err := json.Unmarshal([]byte(`{"Age":18}`), u)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(u) // &{chen 18}
	err = json.Unmarshal([]byte(`{"Name":"hello","Age":18}`), u)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(u) // &{hello 18}
}

自定义解析过程

type DurationConf time.Duration

func (dc *DurationConf) UnmarshalJSON(d []byte) error {
	if len(d) == 0 {
		return errors.New("cann't parse empty string to DurationConf")
	}
	d = bytes.Trim(d, `"`)
	dur, err := time.ParseDuration(string(d))
	if err != nil {
		return err
	}
	*dc = DurationConf(dur)
	return nil
}

注意d中可能会包括双引号。

© 著作权归作者所有

共有 人打赏支持
下一篇: Go笔记-web
漂泊尘埃

漂泊尘埃

粉丝 5
博文 36
码字总数 71385
作品 0
朝阳
私信 提问
译文:笔记本软件 Quiver 简介

英文原文:http://happenapps.com 原文作者:HappenApps, Inc. 中译:不迟any Quiver 程序员的笔记本 Quiver app icon 概述 Quiver 是一款为程序员打造的笔记本。它可以让你方便的在一条笔记...

不迟any
2017/12/10
0
0
go提交json、获取json、解析json

猜你喜欢 Go语言的Json管理模式 golang json string remove field [笔记] Golang JSON go: json解析库go-simplejson使用 Golang 1.6: 数据库NULL值遇到JSON和模板(Template) beego下ie提示下...

d_watson
2016/05/24
43
0
SpringMVC框架 -- json数据交互

一.JSON简单介绍: 参考笔记:JSON简单快速入门 二.json数据交互 请求json 输出json 需要请求数据为json,需要在前端转为json不太方便。不常用 请求key/value、输出json。常用 1.环境搭建 下...

Mr_欢先生
2017/09/28
0
0
Golang学习笔记目录

Golang 介绍 Go语言是谷歌2009发布的第二款开源编程语言。 Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。...

ChainZhang
2017/12/26
0
0
Golang 学习笔记(09)—— json和xml解析

本文为转载,原文:Golang 学习笔记(09)—— json和xml解析 Golang xml package 函数 Marshal Marshal函数返回v的XML编码。 Marshal处理数组或者切片时会序列化每一个元素。Marshal处理指针...

ChainZhang
2018/01/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

乱入Linux界的我是如何学习的

欢迎来到建哥学Linux,咳!咳!咳!开个玩笑哈,我是一个IT男,IT界的入门选手,正在学习Linux。 在之前,一直想进军IT界,学习IT技术,但是苦于没有人指导,也不知道学什么,最开始我自己在...

linuxprobe16
39分钟前
4
0
OSChina 周日乱弹 —— 没时间 没头发 但有钱

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @开源中国总经办主任 :分享齐一的单曲《这个年纪》 《这个年纪》- 齐一 手机党少年们想听歌,请使劲儿戳(这里) @肿肿卷 :我真的可以睡一天...

小小编辑
今天
51
4
Django进阶 1.1 ORM基础—ORM 1.2.1 增删改查之查询 1.2.2 删改增 (1) 1.2.3 删改增 (2)

ORM基础 ORM是Django操作数据库的API,Django的作者将sql语句封装在里面供我们使用。 我们前面还提到过Django提供一个模拟数据库的工具,sqlite,供我们学习测试使用。 如果我们想使用mysql...

隐匿的蚂蚁
今天
3
0
Windows 上安装 Scala

在安装 Scala 之前需要先安装 Java 环境,具体安装的详细方法就不在这里描述了。 您可以自行搜索我们网站中的内容获得其他网站的帮助来获得如何安装 Java 环境的方法。 接下来,我们可以从 ...

honeymose
今天
3
0
数据库篇多表操作

第1章 多表操作 实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系...

stars永恒
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部