Golang ---json解析
golang官方为我们提供了标准的json解析库–encoding/json,大部分情况下,使用它已经够用了。不过这个解析包有个很大的问题–性能。它不够快,如果我们开发高性能、高并发的网络服务就无法满足,这时就需要高性能的json解析库,目前性能比较高的有json-iterator和easyjson。
现在我们需要引进一个高性能的json解析库,这里以json-iterator为例,但是我们全部换掉又不放心,所以可以先小范围的测试下,这时候我们就需要两个解析库并存,那么这时候我们如何选择我们需要的解析库编译和运行呢?
解决上面问题的办法就是条件编译。Go语言为我们提供了基于tags的编译约束来解决这个问题。
统一JSON库
我们先举个例子看看结果。现在我们需要两个库并存,所以我们先得统一这两个库的用法(参考适配器模式),这里我们使用一个自定义的json包来适配encoding/json和json-iterator。
json/json.go
// +build !jsoniter package json import (
"encoding/json"
"fmt"
) func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
fmt.Println("Use [encoding/json] package")
return json.MarshalIndent(v,prefix,indent)
}
json/jsoniter.go
// +build jsoniter package json import (
"fmt"
"github.com/json-iterator/go"
) var (
json = jsoniter.ConfigCompatibleWithStandardLibrary
) func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
fmt.Println("Use [jsoniter] package")
return json.MarshalIndent(v,prefix,indent)
}
目录结构如下:
json
├── json.go
└── jsoniter.go
例子中以MarshalIndent函数为例,我们发现json包下的两个go文件中都有MarshalIndent函数的定义,并且签名一致,但是它们又是使用不同的json解析库实现,这就是我们统一适配包装后的结果,调用统一了。
Demo演示
为了区分调用的是哪个json库的具体实现,打印日志,以便区分。现在我们使用json.MarshalIndent测试一下。
package main import (
"fmt"
"json"
) func main() {
u := user{"Mike", 30}
b, err := json.MarshalIndent(u, "", " ") if err != nil {
fmt.Println(err)
} else {
fmt.Println(string(b))
} } type user struct {
Name string
Age int
}
使用很简单,把一个user结构体对象转为json字符串,并打印出来。我们运行go run main.go看看结果。
Use [encoding/json] package
{
"Name": "Mike",
"Age": 30
}
保持我们默认使用encoding/json库的方式不变。现在我们换一种编译运行方式:
go run -tags=jsoniter main.go
这次运行和上次不同的地方在于我们加了-tags=jsoniter,然后就使用了json-iterator这个json库,这就是选择性的条件编译,达到了我们小部分测试新的json库的目的。
条件编译
我们发现,条件编译的关键在于-tags=jsoniter,也就是-tags这个标志,这就是Go语言为我们提供的条件编译的方式之一。
好了,回过头来看我们刚开始时json/json.go、json/jsoniter.go这两个Go文件的顶部,都有一行注释:
// +build !jsoniter
// +build jsoniter
这两行是Go语言条件编译的关键。+build可以理解为条件编译tags的声明关键字,后面跟着tags的条件。
// +build !jsoniter表示,tags不是jsoniter的时候编译这个Go文件。 // +build jsoniter表示,tags是jsoniter的时候编译这个Go文件。
也就是说,这两种条件是互斥的,只有当tags=jsoniter的时候,才会使用json-iterator,其他情况使用encoding/json。
小结
利用条件编译,我们实现了灵活选择json解析库的目的,且tags只是其中的一部分,Go语言还可以根据Go文件后缀进行条件编译。
Golang ---json解析的更多相关文章
- golang json解析到map中
package main import ( "fmt" "encoding/json" ) type ItemMessage struct { ItemType ...
- Golang中解析json,构造json
json解析是如今(网络)应用程序开发中最不可或缺的一环了.许多语言需要库支持才可以解析.构造json,但Golang凭借着原生库就可以很好地做到这一点. json的基本表现形式有两个:struct与 ...
- Golang Json文件解析为结构体工具-json2go
代码地址如下:http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出到 ...
- golang struct 定义中json``解析说明
在代码学习过程中,发现struct定义中可以包含`json:"name"`的声明,所以在网上找了一些资料研究了一下 package main import ( "enco ...
- 【golang】json数据解析 - 嵌套json解析
@ 目录 1. 通过结构体映射解析 2. 嵌套json解析-map 1. 通过结构体映射解析 原数据结构 解析 // 结构体 type contractJson struct { Data []tra ...
- golang json
1.Go语言的JSON 库 Go语言自带的JSON转换库为 encoding/json 1.1)其中把对象转换为JSON的方法(函数)为 json.Marshal(),其函数原型如下 func Mar ...
- golang json用法讲解
简介 json格式可以算我们日常最常用的序列化格式之一了,Go语言作为一个由Google开发,号称互联网的C语言的语言,自然也对JSON格式支持很好.但是Go语言是个强类型语言,对格式要求极其严格而J ...
- Golang配置文件解析-oozgconf
代码地址如下:http://www.demodashi.com/demo/14411.html 简介 oozgconf基于Golang开发,用于项目中配置文件的读取以及加载,是一个轻量级的配置文件工具 ...
- Golang JSON操作汇总
直接把结构体编码成json数据 package main import ( "encoding/json" "fmt" _ "os" ) t ...
随机推荐
- 【13NOIP提高组】转圈游戏(信息学奥赛一本通 1875)(洛谷 1965)
题目描述 nn 个小描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号 ...
- LSF 作业系统常用命令
LSF(Load Sharing Facility)是一个被广泛使用的作业管理系统,具有高吞吐.配置灵活的优点.通过 LSF 集中监控和调度,可以充分利用计算机的CPU.内存.磁盘等资源. bqueu ...
- TypeScript 真香系列——接口篇
接口带来了什么好处 好处One —— 过去我们写 JavaScript JavaScript 中定义一个函数,用来获取一个用户的姓名和年龄的字符串: const getUserInfo = funct ...
- 有关于服务端模板注入(ssti攻击)——BUUCTF - easy_tornado
打开题目出现3个链接 /flag.txt 中提示flag in /fllllllllllllag /welcome.txt 中提示 render /hints.txt 中提示 md5(cookie_s ...
- wordpress 本地环境安装
1. 下载xmapp 2. 安装mysql 3. 启动xmapp的数据库与Apache,通常无法启动原因. mac的先关闭自己的数据库,系统偏好设置-MySQL Apache的端口默认是80,一般会被 ...
- Android Sensor 架构深入剖析【转】
本文转载自: 1.Android sensor架构 Android4.0系统内置对传感器的支持达13种,它们分别是:加速度传感器 (accelerometer).磁力传感器(magnetic fiel ...
- ubuntu16 修改gitlab root密码
搭建了一个gitlab的git服务器,默认的管理员为root; 长时间不用root忘记了root密码: 我们可以在服务器上直接重置root的密码: 以下操作在终端下执行 #进入gitlab控制台 su ...
- 设置ESXi宿主机开机自动启动虚拟机
转载于 https://blog.csdn.net/Form_/article/details/71170813 在百度上面找了一圈都是讲ESXi6.0之前的版本,在VMware vSphere Cl ...
- PMP 第9~10章错题总结
1.组织分解结构把组织中的部门与项目中的工作包联系起来2.管理项目团队时应该使用冲突管理3.职责分配矩阵(RAM)显示了分配给每个工作包的项目资源,用于说明工作包或活动与项目团队成员之间的关系.而RA ...
- java jdbc使用SSH隧道连接mysql数据库demo
java jdbc使用SSH隧道连接mysql数据库demo 本文链接:https://blog.csdn.net/earbao/article/details/50216999 packag ...