<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          XJSON 是如何實現(xiàn)四則運(yùn)算的?

          共 3175字,需瀏覽 7分鐘

           ·

          2022-07-16 13:43

          前言

          在上一篇中介紹了 xjson 的功能特性以及使用查詢語法快速方便的獲取 JSON 中的值。

          同時這次也更新了一個版本,主要是兩個升級:

          1. 對轉(zhuǎn)義字符的支持。
          2. 性能優(yōu)化,大約提升了30%??。

          轉(zhuǎn)義字符

          先說第一個轉(zhuǎn)義字符,不管是原始 JSON 字符串中存在轉(zhuǎn)義字符,還是查詢語法中存在轉(zhuǎn)義字符都已經(jīng)支持,具體用法如下:

           str = `{"1a.b.[]":"b"}`
           get = Get(str, "1a\\.b\\.\\[\\]")
           assert.Equal(t, get.String(), "b")

           str = `{".":"b"}`
           get = Get(str, "\\.")
           assert.Equal(t, get.String(), "b")

           str = `{"a":"{\"a\":\"123\"}"}`
           get = Get(str, "a")
           fmt.Println(get)
           assert.Equal(t, get.String(), "{\"a\":\"123\"}")
           assert.Equal(t, Get(get.String(), "a").String(), "123")

           str = `{"a":"{\"a\":[1,2]}"}`
           get = Get(str, "a")
           fmt.Println(get)
           assert.Equal(t, get.String(), "{\"a\":[1,2]}")
           assert.Equal(t, Get(get.String(), "a[0]").Int(), 1)

          性能優(yōu)化

          性能也有部分優(yōu)化,大約比上一版本提升了 30%。

          pkg: github.com/crossoverJie/xjson/benckmark
          cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
          BenchmarkDecode-12            14968      77130 ns/op    44959 B/op     1546 allocs/op
          PASS

          ------------------------------------
          pkg: github.com/crossoverJie/xjson/benckmark
          cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
          BenchmarkDecode-12            19136      62960 ns/op    41593 B/op     1407 allocs/op
          PASS

          但總體來說還有不少優(yōu)化空間,主要是上限畢竟低,和官方庫比還是有不小的差距。

          實現(xiàn)四則運(yùn)算

          接下來聊聊四則運(yùn)算是如何實現(xiàn)的,這本身算是一個比較有意思的 feature,雖然用的場景不多??。

          先來看看是如何使用的:

           json :=`{"alice":{"age":10},"bob":{"age":20},"tom":{"age":20}}`
           query := "(alice.age+bob.age) * tom.age"
           arithmetic := GetWithArithmetic(json, query)
           assert.Equal(t, arithmetic.Int(), 600)

          輸入一個 JSON 字符串以及計算公式然后得到計算結(jié)果。

          其實實現(xiàn)原理也比較簡單,總共分為是三步:

          1. json 進(jìn)行詞法分析,得到一個四則運(yùn)算的第一步 token
          2. 基于該 token 流,生產(chǎn)出最終的四則運(yùn)算表達(dá)式,比如 (3+2)*5
          3. 調(diào)用四則運(yùn)算處理器,拿到最終結(jié)果。

          先看第一步,根據(jù) (alice.age+bob.age) * tom.age 解析出 token

          第二步,解析該 token,碰到 Identifier 類型時,將其解析為具體的數(shù)據(jù)。而其他類型的 token 直接拼接字符串即可,最終生成表達(dá)式:(10+20)*20

          這一步的核心功能是由 xjson.Get(json, query) 函數(shù)提供的。

          關(guān)鍵代碼如下圖所示:

          最終的目的就是能夠生成一個表達(dá)式,只要拿到這個四則運(yùn)算表達(dá)式便能得到最終計算結(jié)果。

          而最終的計算邏輯其實也挺簡單,構(gòu)建一個 AST 樹,然后深度遍歷遞歸求解即可,如下圖所示:

          這一步的核心功能是有之前實現(xiàn)的腳本解釋器 gscipt 提供的。

          感興趣的朋友可以查看源碼。

          總結(jié)

          一個 JSON 庫的功能其實并不多,歡迎大家分享平時用 JSON 庫的常用功能;也歡迎大家體驗下這個庫。

          源碼地址:https://github.com/crossoverJie/xjson



          往期推薦



          用面向?qū)ο蟮姆绞讲僮?JSON 甚至還能做四則運(yùn)算 JSON 庫

          幾百行代碼實現(xiàn)一個 JSON 解析器

          幾百行代碼實現(xiàn)一個腳本解釋器

          分享一個 SpringCloud Feign 中所埋藏的坑

          擼了一個 Feign 增強(qiáng)包 V2.0 升級版

           

          點(diǎn)分享

          點(diǎn)點(diǎn)贊

          點(diǎn)在看

           

          瀏覽 58
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一区二区在线不卡 | 亚洲最大视频 | 夜夜骑青青草夜夜嗨 | 中文无码在线播放 | 热久久免费在线视频 |