版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第go面向?qū)ο蠓绞讲僮鱆SON庫(kù)實(shí)現(xiàn)四則運(yùn)算目錄前言面向?qū)ο蟮姆绞讲僮鱆SON實(shí)現(xiàn)原理對(duì)JSON做四則運(yùn)算總結(jié)
前言
在之前實(shí)現(xiàn)的JSON解析器中當(dāng)時(shí)只實(shí)現(xiàn)了將一個(gè)JSON字符串轉(zhuǎn)換為一個(gè)JSONObject,并沒(méi)有將其映射為一個(gè)具體的struct;如果想要獲取值就需要先做斷言將其轉(zhuǎn)換為map或者是切片再來(lái)獲,會(huì)比較麻煩。
decode,err:=xjson.Decode(`{"glossary":{"title":"exampleglossary","age":1}}`)
assert.Nil(t,err)
glossary:=v["glossary"].(map[string]interface{})
assert.Equal(t,glossary["title"],"exampleglossary")
assert.Equal(t,glossary["age"],1)
但其實(shí)轉(zhuǎn)念一想,部分場(chǎng)景我們甚至我們只需要拿到JSON中的某個(gè)字段的值,這樣還需要先聲明一個(gè)struct會(huì)略顯麻煩。
于是我也打算增加類(lèi)似的功能,使用方式如下:
最后還加上了一個(gè)四則運(yùn)算的功能。
面向?qū)ο蟮姆绞讲僮鱆SON
因?yàn)楣δ茴?lèi)似,所以我參考了tidwall的API但去掉一些我覺(jué)得暫時(shí)用不上的特性,并調(diào)整了一點(diǎn)語(yǔ)法。
當(dāng)前這個(gè)版本只能通過(guò)確定的key加上.點(diǎn)符號(hào)訪問(wèn)數(shù)據(jù),如果是數(shù)組則用[index]的方式訪問(wèn)下標(biāo)。
[]符號(hào)訪問(wèn)數(shù)組我覺(jué)得要更符合直覺(jué)一些。
以下是一個(gè)包含多重嵌套JSON的訪問(wèn)示例:
str:=`
"name":"bob",
"age":20,
"skill":{
"lang":[
"go":{
"feature":[
"goroutine",
"channel",
"simple",
true
name:=xjson.Get(str,"name")
assert.Equal(t,name.String(),"bob")
age:=xjson.Get(str,"age")
assert.Equal(t,age.Int(),20)
assert.Equal(t,xjson.Get(str,"skill.lang[0].go.feature[0]").String(),"goroutine")
assert.Equal(t,xjson.Get(str,"skill.lang[0].go.feature[1]").String(),"channel")
assert.Equal(t,xjson.Get(str,"skill.lang[0].go.feature[2]").String(),"simple")
assert.Equal(t,xjson.Get(str,"skill.lang[0].go.feature[3]").Bool(),true)
這樣的語(yǔ)法使用個(gè)人覺(jué)得還是滿符合直覺(jué)的,相信對(duì)使用者來(lái)說(shuō)也比較簡(jiǎn)單。
返回值參考了tidwall使用了一個(gè)Result對(duì)象,它提供了多種方法可以方便的獲取各種類(lèi)型的數(shù)據(jù)
func(rResult)String()string
func(rResult)Bool()bool
func(rResult)Int()int
func(rResult)Float()float64
func(rResult)Map()map[string]interface{}
func(rResult)Array()*[]interface{}
func(rResult)Exists()bool
比如使用Map()/Array()這兩個(gè)函數(shù)可以將JSON數(shù)據(jù)映射到map和切片中,當(dāng)然前提是傳入的語(yǔ)法返回的是一個(gè)合法JSONObject或數(shù)組。
實(shí)現(xiàn)原理
在實(shí)現(xiàn)之前需要先定義一個(gè)基本語(yǔ)法,主要支持以下四種用法:
單個(gè)key的查詢:Get(json,name)嵌套查詢:Get(json,)數(shù)組查詢:Get(json,obj.array[0])數(shù)組嵌套查詢:Get(json,obj.array[0].obj2.obj3[1].name)
語(yǔ)法很簡(jiǎn)單,符合我們?nèi)粘=佑|到語(yǔ)法規(guī)則,這樣便可以訪問(wèn)到JSON數(shù)據(jù)中的任何一個(gè)值。
其實(shí)實(shí)現(xiàn)過(guò)程也不復(fù)雜,我們已經(jīng)在上一文中實(shí)現(xiàn)將JSON字符串轉(zhuǎn)換為一個(gè)JSONObject了。
這次只是額外再解析剛才定義的語(yǔ)法為token,然后解析該token的同時(shí)再?gòu)纳珊玫腏SONObject中獲取數(shù)據(jù)。
最后在解析完token時(shí)拿到的JSONObject數(shù)據(jù)返回即可。
我們以這段查詢代碼為例:
首先第一步是對(duì)查詢語(yǔ)法做詞法分析,最終得到下圖的token。
在詞法分析過(guò)程中也可以做簡(jiǎn)單的語(yǔ)法校驗(yàn);比如如果包含數(shù)組查詢,并不是以]符號(hào)結(jié)尾時(shí)就拋出語(yǔ)法錯(cuò)誤。
接著我們遍歷語(yǔ)法的token。如下圖所示:
每當(dāng)遍歷到token類(lèi)型為Key時(shí)便從當(dāng)前的JSONObject對(duì)象中獲取數(shù)據(jù),并用獲取到的值替覆蓋為當(dāng)前的JSONObject。
其中每當(dāng)遇到.[]這樣的token時(shí)便消耗掉,直到我們將token遍歷完畢,這時(shí)將當(dāng)前JSONObject返回即可。
在遍歷過(guò)程中當(dāng)遇到非法格式時(shí),比如obj_list[1.]便會(huì)返回一個(gè)空的JSONObject。
語(yǔ)法校驗(yàn)這點(diǎn)其實(shí)也很容易辦到,因?yàn)楦鶕?jù)我們的語(yǔ)法規(guī)則,Array中的index后一定緊接的是一個(gè)EndArray,只要不是一個(gè)EndArray便能知道語(yǔ)法不合法了。
有興趣的可以看下解析過(guò)程的源碼:
/crossoverJie/xjson/blob/cfbca51cc9bc0c77e6cb9c9ad3f964b2054b3826/json.go#L46
對(duì)JSON做四則運(yùn)算
str:=`{"name":"bob","age":10,"magic":10.1,"score":{"math":[1,2]}}`
result:=GetWithArithmetic(str,"(age+age)*age+magic")
assert.Equal(t,result.Float(),210.1)
result=GetWithArithmetic(str,"(age+age)*age")
assert.Equal(t,result.Int(),200)
result=GetWithArithmetic(str,"(age+age)*age+score.math[0]")
assert.Equal(t,result.Int(),201)
result=GetWithArithmetic(str,"(age+age)*age-score.math[0]")
assert.Equal(t,result.Int(),199)
result=GetWithArithmetic(str,"
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026東風(fēng)汽車(chē)集團(tuán)躍創(chuàng)科技有限公司(零部件事業(yè)部)招聘2人考試備考題庫(kù)及答案解析
- 2026云南怒江州福貢縣機(jī)關(guān)事務(wù)服務(wù)中心招聘行政中心安保人員1人考試參考題庫(kù)及答案解析
- 2026西安雁塔區(qū)大雁塔社區(qū)衛(wèi)生服務(wù)中心招聘(2人)考試備考試題及答案解析
- 2026云南玉溪市澄江市化石地自然博物館招聘7人考試備考試題及答案解析
- 2026年蕪湖東站貨運(yùn)檢查員勞務(wù)派遣工招聘12人考試備考試題及答案解析
- 2024年河北省邯鄲市磁縣小升初數(shù)學(xué)試卷(含答案解析)
- 2026云南玉溪市紅塔區(qū)玉興街道黨群服務(wù)中心公益性崗位招聘1人考試參考題庫(kù)及答案解析
- 2026福建泉州市安溪縣司法局招聘4人考試備考題庫(kù)及答案解析
- 2026浙江四方集團(tuán)有限公司招聘勞務(wù)派遣人員擬錄用公示考試參考題庫(kù)及答案解析
- 2026年1月廣西桂林市灌陽(yáng)縣人民醫(yī)院人才招聘11人考試參考題庫(kù)及答案解析
- 山東省濟(jì)南市2024年1月高二上學(xué)期學(xué)情期末檢測(cè)英語(yǔ)試題含解析
- 供應(yīng)鏈管理工作計(jì)劃與目標(biāo)
- 口腔門(mén)診醫(yī)療質(zhì)控培訓(xùn)
- (正式版)JBT 9229-2024 剪叉式升降工作平臺(tái)
- HGT4134-2022 工業(yè)聚乙二醇PEG
- GB/T 15231-2023玻璃纖維增強(qiáng)水泥性能試驗(yàn)方法
- 小學(xué)教職工代表大會(huì)提案表
- ESC2023年心臟起搏器和心臟再同步治療指南解讀
- 《泰坦尼克號(hào)》拉片分析
- GB/T 2624.1-2006用安裝在圓形截面管道中的差壓裝置測(cè)量滿管流體流量第1部分:一般原理和要求
- 基層版胸痛中心建設(shè)標(biāo)準(zhǔn)課件
評(píng)論
0/150
提交評(píng)論