golang官方为我们提供了标准的json解析库–encoding/json,大部分情况下,使用它已经够用了。不过这个解析包有个很大的问题–性能。它不够快,如果我们开发高性能、高并发的网络服务就无法满足,这时就需要高性能的json解析库,目前性能比较高的有json-iteratoreasyjson

现在我们需要引进一个高性能的json解析库,这里以json-iterator为例,但是我们全部换掉又不放心,所以可以先小范围的测试下,这时候我们就需要两个解析库并存,那么这时候我们如何选择我们需要的解析库编译和运行呢?

解决上面问题的办法就是条件编译。Go语言为我们提供了基于tags的编译约束来解决这个问题。

统一JSON库

我们先举个例子看看结果。现在我们需要两个库并存,所以我们先得统一这两个库的用法(参考适配器模式),这里我们使用一个自定义的json包来适配encoding/jsonjson-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.gojson/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解析的更多相关文章

  1. golang json解析到map中

    package main import ( "fmt" "encoding/json" ) type ItemMessage struct { ItemType ...

  2. Golang中解析json,构造json

    json解析是如今(网络)应用程序开发中最不可或缺的一环了.许多语言需要库支持才可以解析.构造json,但Golang凭借着原生库就可以很好地做到这一点. json的基本表现形式有两个:struct与 ...

  3. Golang Json文件解析为结构体工具-json2go

    代码地址如下:http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出到 ...

  4. golang struct 定义中json``解析说明

    在代码学习过程中,发现struct定义中可以包含`json:"name"`的声明,所以在网上找了一些资料研究了一下 package main import ( "enco ...

  5. 【golang】json数据解析 - 嵌套json解析

    @ 目录 1. 通过结构体映射解析 2. 嵌套json解析-map 1. 通过结构体映射解析 原数据结构 解析 // 结构体 type contractJson struct { Data []tra ...

  6. golang json

    1.Go语言的JSON 库 Go语言自带的JSON转换库为 encoding/json 1.1)其中把对象转换为JSON的方法(函数)为 json.Marshal(),其函数原型如下 func Mar ...

  7. golang json用法讲解

    简介 json格式可以算我们日常最常用的序列化格式之一了,Go语言作为一个由Google开发,号称互联网的C语言的语言,自然也对JSON格式支持很好.但是Go语言是个强类型语言,对格式要求极其严格而J ...

  8. Golang配置文件解析-oozgconf

    代码地址如下:http://www.demodashi.com/demo/14411.html 简介 oozgconf基于Golang开发,用于项目中配置文件的读取以及加载,是一个轻量级的配置文件工具 ...

  9. Golang JSON操作汇总

    直接把结构体编码成json数据 package main import ( "encoding/json" "fmt" _ "os" ) t ...

随机推荐

  1. 了解Vuex状态管理模式的理解强化指南

    1 Vuex是什么呢?它是Vue的状态管理模式,在使用vue的时候,需要在vue中各个组件之间传递值是很痛苦的,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被改变,所有引用该值的地 ...

  2. 驱动中遍历模块,以及获取ntoskrnl.exe基址

    方法是基于PsLoadModuleList方式 驱动中遍历模块 一丶简介 简介: 进入内核了.遍历内核中使用的模块该怎么办. 其实在驱动中.我们的DriverEntry入口位置. 提供了两个参数. 一 ...

  3. nginx 正向代理配置

    需求场景:从以下俩张图可以比较直观的理解正向代理的作用(在其他文章中会表示为“http代理”,注意当前文档的配置不支持https代理) Nginx正向代理配置文件: server{ listen de ...

  4. 【AtCoder】 ARC 098

    link C-Attention 题意:一个字符队列,每个位置是\(W\)或\(E\),计算最小的修改数量,使得存在一个位置,它之前的都是\(E\),之后的都是\(F\) #include<bi ...

  5. lightgbm GPU版本安装

     python机器学习-乳腺癌细胞挖掘(博主亲自录制视频)https://study.163.com/course/introduction.htm?courseId=1005269003&u ...

  6. linux zip命令 tar命令 【压缩、解压缩】参数列表:

    linux zip命令参数列表:   -a 将文件转成ASCII模式 -F 尝试修复损坏的压缩文件 -h 显示帮助界面 -m 将文件压缩之后,删除源文件   -n 特定字符串 不压缩具有特定字尾字符串 ...

  7. Go 切片:用法和本质

    2011/01/05 引言 Go的切片类型为处理同类型数据序列提供一个方便而高效的方式. 切片有些类似于其他语言中的数组,但是有一些不同寻常的特性. 本文将深入切片的本质,并讲解它的用法. 数组 Go ...

  8. osgb文件过大,可以通过Compressor=zlib对纹理进行压缩

    osg::ref_ptr<osgDB::ReaderWriter::Options> options = new osgDB::ReaderWriter::Options; options ...

  9. Java8相关底层

    Java8是往并行方向走的.由面向对象到函数式编程. 在支持函数式编程的同时还可以支持面向对象的开发. 在JDK1.8里面,接口里面可以有实现方法的!默认方法,default.实现这个接口. 接口里面 ...

  10. 上传下载execl

    ajax上传execl + easyexecl解析execl <!DOCTYPE html> <html> <head> <meta charset=&quo ...