最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go面向?qū)ο蠓绞讲僮鱆SON庫實(shí)現(xiàn)四則運(yùn)算

 更新時(shí)間:2022年07月12日 10:32:01   作者:baller  
這篇文章主要為大家介紹了go面向?qū)ο蠓绞讲僮鱆SON庫實(shí)現(xiàn)四則運(yùn)算的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在之前實(shí)現(xiàn)的 JSON 解析器中當(dāng)時(shí)只實(shí)現(xiàn)了將一個(gè) JSON 字符串轉(zhuǎn)換為一個(gè) JSONObject,并沒有將其映射為一個(gè)具體的 struct;如果想要獲取值就需要先做斷言將其轉(zhuǎn)換為 map 或者是切片再來獲,會比較麻煩。

decode, err := xjson.Decode(`{"glossary":{"title":"example glossary","age":1}}`)
assert.Nil(t, err)
glossary := v["glossary"].(map[string]interface{})
assert.Equal(t, glossary["title"], "example glossary")
assert.Equal(t, glossary["age"], 1)

但其實(shí)轉(zhuǎn)念一想,部分場景我們甚至我們只需要拿到 JSON 中的某個(gè)字段的值,這樣還需要先聲明一個(gè) struct 會略顯麻煩。

于是我也打算增加類似的功能,使用方式如下:

最后還加上了一個(gè)四則運(yùn)算的功能。

面向?qū)ο蟮姆绞讲僮?JSON

因?yàn)楣δ茴愃疲晕覅⒖剂?nbsp;tidwall 的 API 但去掉一些我覺得暫時(shí)用不上的特性,并調(diào)整了一點(diǎn)語法。

當(dāng)前這個(gè)版本只能通過確定的 key 加上 . 點(diǎn)符號訪問數(shù)據(jù),如果是數(shù)組則用 [index] 的方式訪問下標(biāo)。
[] 符號訪問數(shù)組我覺得要更符合直覺一些。

以下是一個(gè)包含多重嵌套 JSON 的訪問示例:

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)

這樣的語法使用個(gè)人覺得還是滿符合直覺的,相信對使用者來說也比較簡單。

返回值參考了 tidwall 使用了一個(gè) Result 對象,它提供了多種方法可以方便的獲取各種類型的數(shù)據(jù)

func (r Result) String() string
func (r Result) Bool() bool
func (r Result) Int() int
func (r Result) Float() float64
func (r Result) Map() map[string]interface{}
func (r Result) Array() *[]interface{}
func (r Result) Exists() bool

比如使用 Map()/Array() 這兩個(gè)函數(shù)可以將 JSON 數(shù)據(jù)映射到 map 和切片中,當(dāng)然前提是傳入的語法返回的是一個(gè)合法 JSONObject 或數(shù)組。

實(shí)現(xiàn)原理

在實(shí)現(xiàn)之前需要先定義一個(gè)基本語法,主要支持以下四種用法:

  • 單個(gè) key 的查詢:Get(json,"name")
  • 嵌套查詢: Get(json,"obj1.obj2.obj3.name")
  • 數(shù)組查詢:Get(json,"obj.array[0]")
  • 數(shù)組嵌套查詢:Get(json,"obj.array[0].obj2.obj3[1].name")

語法很簡單,符合我們?nèi)粘=佑|到語法規(guī)則,這樣便可以訪問到 JSON 數(shù)據(jù)中的任何一個(gè)值。

其實(shí)實(shí)現(xiàn)過程也不復(fù)雜,我們已經(jīng)在上一文中實(shí)現(xiàn)將 JSON 字符串轉(zhuǎn)換為一個(gè) JSONObject 了。

這次只是額外再解析剛才定義的語法為 token,然后解析該 token 的同時(shí)再從生成好的 JSONObject 中獲取數(shù)據(jù)。

最后在解析完 token 時(shí)拿到的 JSONObject 數(shù)據(jù)返回即可。

我們以這段查詢代碼為例:

首先第一步是對查詢語法做詞法分析,最終得到下圖的 token。

在詞法分析過程中也可以做簡單的語法校驗(yàn);比如如果包含數(shù)組查詢,并不是以 ] 符號結(jié)尾時(shí)就拋出語法錯(cuò)誤。

接著我們遍歷語法的 token。如下圖所示:

每當(dāng)遍歷到 token 類型為 Key 時(shí)便從當(dāng)前的 JSONObject 對象中獲取數(shù)據(jù),并用獲取到的值替覆蓋為當(dāng)前的 JSONObject。

其中每當(dāng)遇到 . [ ] 這樣的 token 時(shí)便消耗掉,直到我們將 token 遍歷完畢,這時(shí)將當(dāng)前 JSONObject 返回即可。

在遍歷過程中當(dāng)遇到非法格式時(shí),比如 obj_list[1.] 便會返回一個(gè)空的 JSONObject

語法校驗(yàn)這點(diǎn)其實(shí)也很容易辦到,因?yàn)楦鶕?jù)我們的語法規(guī)則,Array 中的 index 后一定緊接的是一個(gè) EndArray,只要不是一個(gè) EndArray 便能知道語法不合法了。

有興趣的可以看下解析過程的源碼:

https://github.com/crossoverJie/xjson/blob/cfbca51cc9bc0c77e6cb9c9ad3f964b2054b3826/json.go#L46

對 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, "score.math[1] / score.math[0]")
assert.Equal(t, result.Int(), 2)

最后我還擴(kuò)展了一下語法,可以支持對 JSON 數(shù)據(jù)中的整形(int、float)做四則運(yùn)算,雖然這是一個(gè)小眾需求,但做完我覺得還挺有意思的,目前在市面上我還沒發(fā)現(xiàn)有類似功能的庫,可能和小眾需求有關(guān)??。

其中核心的四則運(yùn)算邏輯是由之前寫的腳本解釋器提供的:

https://github.com/crossoverJie/gscript

單獨(dú)提供了一個(gè)函數(shù),傳入一個(gè)四則運(yùn)算表達(dá)式返回計(jì)算結(jié)果。

由于上一版本還不支持 float,所以這次專門適配了一下。

限于篇幅,更多關(guān)于這個(gè)四則運(yùn)算的實(shí)現(xiàn)邏輯會在后面繼續(xù)分享。

總結(jié)

至此算是我第一次利用編譯原理的知識解決了一點(diǎn)特定領(lǐng)域問題,在大學(xué)以及工作這些年一直覺得編譯原理比較高深,所以內(nèi)心一直是抗拒的,但經(jīng)過這段時(shí)間的學(xué)習(xí)和實(shí)踐慢慢的也掌握到了一點(diǎn)門道。

不過目前也只是冰山一角,后面的編譯原理后端更是要涉及到計(jì)算機(jī)底層知識,所以依然任重而道遠(yuǎn)。

已上都是題外話,針對于這個(gè)庫我也會長期維護(hù);為了能達(dá)到生產(chǎn)的使用要求,盡量提高了單測覆蓋率,目前是98%。

也歡迎大家使用,提 bug??。

后面會繼續(xù)優(yōu)化,比如支持轉(zhuǎn)義字符、提高性能等

https://github.com/crossoverJie/xjson

以上就是go面向?qū)ο蠓绞讲僮鱆SON庫實(shí)現(xiàn)四則運(yùn)算的詳細(xì)內(nèi)容,更多關(guān)于go面向?qū)ο驤SON庫四則運(yùn)算的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解玩轉(zhuǎn)直播系列之消息模塊演進(jìn)

    詳解玩轉(zhuǎn)直播系列之消息模塊演進(jìn)

    本篇文章針對秀場直播,簡單地描述一下消息模型,說明一下我們消息模型的架構(gòu),并結(jié)合我們一年以來,通過處理不同的業(yè)務(wù)線上問題,來進(jìn)行演進(jìn)式的消息模型架構(gòu)的升級與調(diào)整,將此整理成文,并分享給大家
    2021-06-06
  • Go語言并發(fā)爬蟲的具體實(shí)現(xiàn)

    Go語言并發(fā)爬蟲的具體實(shí)現(xiàn)

    本文主要介紹了Go語言并發(fā)爬蟲的具體實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 如何用go-zero 實(shí)現(xiàn)中臺系統(tǒng)

    如何用go-zero 實(shí)現(xiàn)中臺系統(tǒng)

    這篇文章主要介紹了如何用go-zero 實(shí)現(xiàn)中臺系統(tǒng),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Golang Gin框架實(shí)現(xiàn)文件下載功能的示例代碼

    Golang Gin框架實(shí)現(xiàn)文件下載功能的示例代碼

    本文主要介紹了Golang Gin框架實(shí)現(xiàn)文件下載功能的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • golang下的GOPATH路徑問題及解決

    golang下的GOPATH路徑問題及解決

    為了方便,我一般使用task來管理項(xiàng)目的編譯等事項(xiàng),由于才入門go,所以碰到一個(gè)問題,以此篇為記,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • go語言LeetCode題解720詞典中最長的單詞

    go語言LeetCode題解720詞典中最長的單詞

    這篇文章主要為大家介紹了go語言LeetCode題解720詞典中最長的單詞,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • go語言實(shí)現(xiàn)通過FTP庫自動上傳web日志

    go語言實(shí)現(xiàn)通過FTP庫自動上傳web日志

    這篇文章主要介紹了go語言實(shí)現(xiàn)通過FTP庫自動上傳web日志,非常簡單實(shí)用,需要的小伙伴快來參考下吧。
    2015-03-03
  • GoLang抽獎(jiǎng)系統(tǒng)簡易實(shí)現(xiàn)流程

    GoLang抽獎(jiǎng)系統(tǒng)簡易實(shí)現(xiàn)流程

    這篇文章主要介紹了GoLang抽獎(jiǎng)系統(tǒng)實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • windows下使用vscode搭建golang環(huán)境并調(diào)試的過程

    windows下使用vscode搭建golang環(huán)境并調(diào)試的過程

    這篇文章主要介紹了在windows下使用vscode搭建golang環(huán)境并進(jìn)行調(diào)試,主要包括安裝方法及環(huán)境變量配置技巧,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • GO語言字符串處理Strings包的函數(shù)使用示例講解

    GO語言字符串處理Strings包的函數(shù)使用示例講解

    這篇文章主要為大家介紹了GO語言字符串處理Strings包的函數(shù)使用示例講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04

最新評論

涡阳县| 茂名市| 孝义市| 任丘市| 两当县| 景德镇市| 阿坝县| 格尔木市| 盐城市| 若羌县| 安新县| 湟中县| 康马县| 遵义县| 都江堰市| 荥阳市| 绍兴县| 涿州市| 乐东| 揭阳市| 远安县| 逊克县| 自治县| 临湘市| 东乌珠穆沁旗| 乳山市| 天镇县| 九龙县| 陈巴尔虎旗| 三原县| 招远市| 聂拉木县| 濮阳市| 邢台县| 凤凰县| 凤翔县| 同心县| 外汇| 聊城市| 德阳市| 台湾省|