【Go 推薦】快且靈活的 JSON 解析器 - Jsoniter
一、簡介
什麼是 jsoniter?
jsoniter(json-iterator)是一款快且靈活的 JSON 解析器,同時提供 Java 和 Go 兩個版本。從 dsljson 和 jsonparser 借鑑了大量代碼。
根據官網介紹:Jsoniter 的 Golang 版本可以比標準庫(encoding/json)快 6 倍之多。而且這個性能是在不使用代碼生成的前提下獲得的。
同時官網還提供了完整的 性能評測報告和 性能優化 是怎麼做的的詳盡解釋。
爲什麼用 jsoniter?
這是一個悲傷的故事,在工作的時候碰到了上游接口返回的 json 包括了兩個時間格式(時間戳和字符串),分別用 "createtime" 和 "createTime" 作爲 key。衆所周知 Go 的 json 是大小寫不敏感的,而這兩個字段類型又不同。當我同時解析這兩個字段的時候是可以的,但是當我只解析其中一個字段時就會產生 error。當時妥協選擇了兩個字段同時解析,後來又選擇了更合適的 jsoniter 來控制大小寫敏感。
二、原生 json 演示
通過下面的例子我們可以復現我當時出現的問題。只解析 createtime
package main
import (
"encoding/json"
"fmt"
)
const jsonText = "{\"createtime\":\"2021-04-03T17:41:48\",\"createTime\":1617442908}\n"
func main() {
type co struct {
Createtime string `json:"createtime"`
//CreateTime int `json:"createTime"`
}
var data co
text := []byte(jsonText)
err := json.Unmarshal(text, &data)
fmt.Println(err)
fmt.Printf("%+v", data)
}
打印結果爲:
json: cannot unmarshal number into Go struct field co.createtime of type string
{Createtime:2021-04-03T17:41:48}
只解析 createTime
type co struct {
//Createtime string `json:"createtime"`
CreateTime int `json:"createTime"`
}
打印結果爲:
json: cannot unmarshal string into Go struct field co.createTime of type int
{CreateTime:1617442908}
兩個都解析
type co struct {
Createtime string `json:"createtime"`
CreateTime int `json:"createTime"`
}
打印結果爲:
<nil>
{Createtime:2021-04-03T17:41:48 CreateTime:1617442908}
三、jsoniter 演示
默認不區分大小寫
只解析 createtime
package main
import (
"fmt"
jsoniter "github.com/json-iterator/go"
)
const jsonText = "{\"createtime\":\"2021-04-03T17:41:48\",\"createTime\":1617442908}\n"
func main() {
type co struct {
Createtime string `json:"createtime"`
//CreateTime int `json:"createTime"`
}
var data co
text := []byte(jsonText)
err := jsoniter.Unmarshal(text, &data)
fmt.Println(err)
fmt.Printf("%+v", data)
}
打印結果爲:
main.co.Createtime: ReadString: expects " or n, but found 1, error found in #10 byte of ...|ateTime":1617442908}|..., bigger context ...|{"createtime":"2021-04-03T17:41:48","createTime":1617442908}
|...
{Createtime:}
由此我們還可以看出 json 雖然大小寫不敏感,只解析其中一個字段時也會報錯,但是可以解析正確的結果,jsoniter 默認是無法解析的。
設置爲區分大小寫
package main
import (
"fmt"
jsoniter "github.com/json-iterator/go"
)
const jsonText = "{\"createtime\":\"2021-04-03T17:41:48\",\"createTime\":1617442908}\n"
func main() {
type co struct {
Createtime string `json:"createtime"`
//CreateTime int `json:"createTime"`
}
var data co
text := []byte(jsonText)
json := jsoniter.Config{CaseSensitive: true}.Froze()
err := json.Unmarshal(text, &data)
fmt.Println(err)
fmt.Printf("%+v", data)
}
打印結果爲:
<nil>
{Createtime:2021-04-03T17:41:48}
最後總結一下區別
四、jsoniter 用法
除了像上面這種 jsoniter 自定義的特性,我們還可以將 jsoniter 替代 encoding/json 使用
將
import "encoding/json"
json.Marshal(&data)
替換爲
import jsoniter "github.com/json-iterator/go"
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(&data)
將
import "encoding/json"
json.Unmarshal(input, &data)
替換爲
import jsoniter "github.com/json-iterator/go"
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Unmarshal(input, &data)
參考文檔
-
https://jsoniter.com/index.cn.html
-
https://github.com/json-iterator/go
-
http://jsoniter.com/migrate-from-go-std.html
歡迎加入我們 GOLANG 中國社區:https://gocn.vip/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/e87nDv67hG2asW8vtdsYJw