flysnow_org
背景
encoding/jsonjson-iteratoreasyjson
json-iterator
解决上面问题的办法就是条件编译。做过C/C++开发的都了解它有预编译可以解决这个问题,那么对于Go是没有预编译的,但是Go语言为我们提供了基于tags的编译约束来解决这个问题。
统一JSON库
jsonencoding/jsonjson-iterator
json/json.go
1
2
3
4
5
6
7
8
9
10
11
12
13
// +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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// +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)
}
目录结构如下:
1
2
3
json
├── json.go
└── jsoniter.go
MarshalIndentjsonMarshalIndent
Demo演示
json.MarshalIndent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
import (
"fmt"
"flysnow.org/hello/json"
)
func main() {
u:=user{"飞雪无情","http://www.flysnow.org/","flysnow_org"}
b,err:=json.MarshalIndent(u,""," ")
if err!=nil {
fmt.Println(err)
} else {
fmt.Println(string(b))
}
}
type user struct {
Name string
Blog string
Wechat string
}
usergo run main.go
1
2
3
4
5
6
Use [encoding/json] package
{
"Name": "飞雪无情",
"Blog": "http://www.flysnow.org/",
"Wechat": "flysnow_org"
}
encoding/json
1
2
3
4
5
6
7
8
-> go run -tags=jsoniter main.go
Use [jsoniter] package
{
"Name": "飞雪无情",
"Blog": "http://www.flysnow.org/",
"Wechat": "flysnow_org"
}
-tags=jsoniterjson-iterator
go build -tags=jsoniter .json-iterator
条件编译
-tags=jsoniter-tags
json/json.gojson/jsoniter.go
1
2
3
// +build !jsoniter
// +build jsoniter
+build
// +build !jsoniterjsoniter// +build jsoniterjsoniter
tags=jsoniterjson-iteratorencoding/json
小结
利用条件编译,我们实现了灵活选择json解析库的目的,除此之外,有时间我再细讲,而且tags只是其中的一部分,Go语言还可以根据Go文件后缀进行条件编译。
flysnow_org