文档章节

Go笔记-json

漂泊尘埃
 漂泊尘埃
发布于 2017/02/28 15:01
字数 687
阅读 10
收藏 0
点赞 0
评论 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中可能会包括双引号。

© 著作权归作者所有

共有 人打赏支持
漂泊尘埃

漂泊尘埃

粉丝 5
博文 35
码字总数 70992
作品 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
01/03
0
0
Python爬虫实战-抓取《盗墓笔记》所有章节及链接

image.png 本次以一个盗墓笔记的小说阅读网(http://seputu.com)为例,抓取盗墓笔记的标题、章节名和链接,如下图 前提: 这是一个静态网站,标题、章节都不是由JavaScript动态加载的,无代...

爱吃西瓜的番茄酱
2017/11/06
0
0
CoAP协议学习笔记 2.3 阿里云IoT平台接入 了解下物模型

这篇笔记涉及 阿里云CoAP接入, CoAP协议学习笔记可点此查看。 1 前言 上一篇使用基础版产品进行接入,此种应用,阿里云IoT平台作为一个数据管道。另外阿里云物联网套件中还提供了高级版产品...

iotisan
05/11
0
0
社区 APP 开发笔记( 5 篇)教你从零开发 APP!

前端使用的是apicloud,页面是在玩转晋城的基础上修改的。 后端是java,使用了JFinal框架。 前端通过ajax方式与后台交互,使用的是apicloud的方法 后台执行业务逻辑和数据库操作,给前台返回j...

API_Cloud
2015/02/11
1K
4
Go圣经-学习笔记之复合类型(三)

上一篇 Go圣经-学习笔记之复合类型(二) 下一篇 Go圣经-学习笔记之函数和错误处理 json数据的序列化和反序列化 json的全称是Javascript object notation, 中文全称:js对象表示法。在序列化和...

cdh0805010
2017/10/24
0
0
使用jQuery POST提交数据返回的JSON是字符串不能解析为JSON对象

刚开始介入编程,很多东西自己不是一下就能搞定的,刚开始犯的错还不少。 借助CSDN博客当做自己的笔记。 今天用jQuery的POST提交数据,我需要用他返回的数据, [javascript] view plaincopyp...

蜗牛奔跑
2015/07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Python PIPEs

https://www.python-course.eu/pipes.php https://www.tutorialspoint.com/python/os_pipe.htm

zungyiu
4分钟前
0
0
gRPC学习笔记

gRPC编程流程 1. proto文件定义 proto文件用于定义需要通过gRPC生成的接口,可以理解为接口定义文档 2. 通过构建工具生成服务基类代码-Maven或Gradle 3. 服务端开发 服务端实现类须实现通过构...

OSC_fly
23分钟前
0
0
Docker Mac (三) Dockerfile 及命令

Dockerfile 最近学习docker的时候,遇到一件怪事,关于docker镜像可能会被破坏,还不知道它会有此措施 所以需要了解构建Dockerfile的正确方法 Dockerfile是由一系列命令和参数构成的脚本,这些命...

___大侠
50分钟前
0
0
Android Studio+NDK+Cmake 移植FFmpeg-4.0.2命令行工具

一、编译 参考大神的帖子,亲测一次编译成功:https://blog.csdn.net/bobcat_kay/article/details/80889398 鉴于以前查文档的经验,这里附上编写例子的时间:2018年7月22日 我用的是ubantu,...

她叫我小渝
51分钟前
0
0
mysql创建数据库

登录MYSQL mysql -u root -p 脚本创建数据库WeChat,并制定默认的字符集是utf8mb4。 CREATE DATABASE Wechat DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; 授权 grant all......

niithub
今天
0
0
svn: Unable to connect to a repository URL 的解决方案

错误图示: 解决办法:清除本地保存的授权信息; 1:右键点击本地文件夹,选择设置; TortoiseSVN -> Settings 2:在弹出的对话框中选择 Saved Data, 右侧选择:授权地方清理所有。 然后点确...

宁哥实战课堂
今天
1
0
sleep与wait的区别

Thread.sleep(XXX)方法消耗CPU吗? 这个知识点是我之前认识一直有错误的一个知识点,在我以前的认识里面,我一直认为Thread.sleep(1000)的这一秒钟的时间内,线程的休眠是一直占用着CPU的时间...

码代码的小司机
今天
1
0
20位活跃在Github上的国内技术大牛 leij 何小鹏 亚信

本文列举了20位在Github上非常活跃的国内大牛,看看其中是不是很多熟悉的面孔? 1. lifesinger(玉伯) Github主页: https://github.com/lifesinger 微博:@ 玉伯也叫射雕 玉伯(王保平),...

海博1600
今天
1
0
Mybatis收集配置

一、Mybatis取Clob数据 1、Mapper.xml配置 <resultMap type="com.test.User" id="user"> <result column="id" property="id"/> <result column="json_data" property="jsonData" ......

星痕2018
今天
1
0
centos7设置以多用户模式启动

1、旧版本linux系统修改inittab文件,在新版本执行vi /etc/inittab 会有以下提示 # inittab is no longer used when using systemd. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON......

haha360
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部