1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        效率提高80%,Go開發(fā)必備的庫與工具!

        共 7732字,需瀏覽 16分鐘

         ·

        2021-11-03 16:55

        20995c00780e5cd1229f3ca33122c61f.webp

        不知不覺寫 Go 已經(jīng)快一年了,上線了大大小小好幾個項目;心態(tài)也經(jīng)歷了幾輪變化。

        因為我個人大概前五年時間寫的是 Java ,中途寫過一年多的 Python,所以剛接觸到 Go 時的感覺如下圖:734166d2fb65c871e4b759a075cd9776.webp

        既沒有 Java 的生態(tài),也沒有 Python 這么多語法糖。

        寫到現(xiàn)在的感覺就是:3c78859be755aac50c870cbe46a0898b.webp

        這里就不討論這幾門語言誰強誰弱了;重點和大家分享下我們?nèi)粘i_發(fā)中所使用到的一些第三方庫與工具。

        這里我主要將這些庫分為兩類:

        • 業(yè)務(wù)開發(fā)
        • 基礎(chǔ)工具開發(fā)
        業(yè)務(wù)開發(fā)

        首先是業(yè)務(wù)開發(fā),主要包含了 web、數(shù)據(jù)庫、Redis 等。

        Gin ??????????

        首先是 Gin,一款 HTTP 框架,使用簡單、性能優(yōu)秀、資料眾多;你還在猶豫選擇哪款框架時,那就選擇它吧,基本沒錯。

        當(dāng)然和它配套的 github.com/swaggo/gin-swagger swagger 工具也是剛需;利用它可以生成 swagger 文檔。

        GORM ??????????

        GORM 也沒啥好說的,如果你喜歡 orm 的方式操作數(shù)據(jù)庫,那就選它吧;同樣的也是使用簡單、資料較多。

        如果有讀寫分離需求,也可以使用 GORM 官方提供的插件 https://github.com/go-gorm/dbresolver ,配合 GORM 使用也是非常簡單。

        errors ??????????

        Go 語言自身提供的錯誤處理比較簡單,https://github.com/pkg/errors 提供了更強大的功能,比如:

        • 包裝異常
        • 包裝堆棧等。

        常用的有以下 API:

        //?WithMessagef?annotates?err?with?the?format?specifier.
        func?WithMessagef(err?error,?format?string,?args?...interface{})?error

        //?WithStack?annotates?err?with?a?stack?trace?at?the?point?WithStack?was?called.
        func?WithStack(err?error)?error

        zorolog ??????????

        Go 里的日志打印庫非常多,日志在日常開發(fā)中最好就是存在感低;也就是說性能強(不能影響到業(yè)務(wù)代碼)、使用 API 簡單。

        "github.com/rs/zerolog/log"
        log.Debug().Msgf("OrderID?:%s",?"12121")

        excelize

        https://github.com/qax-os/excelize是一個讀寫 Excel 的庫,基本上你能遇到的 Excel 操作它都能實現(xiàn)。

        now ????????

        https://github.com/jinzhu/now 是一個時間工具庫:

        • 獲取當(dāng)前的年月日、時分秒。
        • 不同時區(qū)支持。
        • 最后一周、最后一個月等。
        import?"github.com/jinzhu/now"

        time.Now()?//?2013-11-18?17:51:49.123456789?Mon

        now.BeginningOfMinute()????????//?2013-11-18?17:51:00?Mon
        now.BeginningOfHour()??????????//?2013-11-18?17:00:00?Mon
        now.BeginningOfDay()???????????//?2013-11-18?00:00:00?Mon
        now.BeginningOfWeek()??????????//?2013-11-17?00:00:00?Sun
        now.BeginningOfMonth()?????????//?2013-11-01?00:00:00?Fri
        now.BeginningOfQuarter()???????//?2013-10-01?00:00:00?Tue
        now.BeginningOfYear()??????????//?2013-01-01?00:00:00?Tue

        now.EndOfMinute()??????????????//?2013-11-18?17:51:59.999999999?Mon
        now.EndOfHour()????????????????//?2013-11-18?17:59:59.999999999?Mon
        now.EndOfDay()?????????????????//?2013-11-18?23:59:59.999999999?Mon
        now.EndOfWeek()????????????????//?2013-11-23?23:59:59.999999999?Sat
        now.EndOfMonth()???????????????//?2013-11-30?23:59:59.999999999?Sat
        now.EndOfQuarter()?????????????//?2013-12-31?23:59:59.999999999?Tue
        now.EndOfYear()????????????????//?2013-12-31?23:59:59.999999999?Tue

        now.WeekStartDay?=?time.Monday?//?Set?Monday?as?first?day,?default?is?Sunday
        now.EndOfWeek()????????????????//?2013-11-24?23:59:59.999999999?Sun

        Decimal ????????

        當(dāng)業(yè)務(wù)上需要精度計算時 https://github.com/shopspring/decimal 可以幫忙。

        import?(
        ?"fmt"
        ?"github.com/shopspring/decimal"
        )

        func?main()?{
        ?price,?err?:=?decimal.NewFromString("136.02")

        ?quantity?:=?decimal.NewFromInt(3)
        ?fee,?_?:=?decimal.NewFromString(".035")
        ?taxRate,?_?:=?decimal.NewFromString(".08875")

        ?subtotal?:=?price.Mul(quantity)

        ?preTax?:=?subtotal.Mul(fee.Add(decimal.NewFromFloat(1)))

        ?total?:=?preTax.Mul(taxRate.Add(decimal.NewFromFloat(1)))

        ?fmt.Println("Subtotal:",?subtotal)??????????????????????//?Subtotal:?408.06
        ?fmt.Println("Pre-tax:",?preTax)?????????????????????????//?Pre-tax:?422.3421
        ?fmt.Println("Taxes:",?total.Sub(preTax))????????????????//?Taxes:?37.482861375
        ?fmt.Println("Total:",?total)????????????????????????????//?Total:?459.824961375
        ?fmt.Println("Tax?rate:",?total.Sub(preTax).Div(preTax))?//?Tax?rate:?0.08875
        }

        基本上你能想到的精度轉(zhuǎn)換它都能做到;配合上 GORM 也可以將 model 字段聲明為 decimal 的類型,數(shù)據(jù)庫對應(yīng)的也是 decimal ,這樣使用起來時會更方便。

        Amount?decimal.Decimal?`gorm:"column:amout;default:0.0000;NOT?NULL"?json:"amout"`?

        configor ????????

        https://github.com/jinzhu/configor 是一個配置文件讀取庫,支持 YAML/JSON/TOML 等格式。

        go-cache ??????

        https://github.com/patrickmn/go-cache 是一個類似于 Java 中的 Guava cache,線程安全,使用簡單;不需要分布式緩存的簡單場景可以考慮。

        ?c?:=?cache.New(5*time.Minute,?10*time.Minute)
        ?//?Set?the?value?of?the?key?"foo"?to?"bar",?with?the?default?expiration?time
        ?c.Set("foo",?"bar",?cache.DefaultExpiration)

        copier ??????

        https://github.com/jinzhu/copier 看名字就知道這是一個數(shù)據(jù)復(fù)制的庫,與 Java 中的 BeanUtils.copy() 類似;可以將兩個字段相同但對象不同的 ?struct 進行數(shù)據(jù)復(fù)制,也支持深拷貝。

        func?Copy(toValue?interface{},?fromValue?interface{})?(err?error)?

        在我們需要一個臨時 struct 來存放數(shù)據(jù)時很有用,特別是一個 struct 中字段非常多時,一個個來回賦值確實有點費手指。

        但也要注意不要什么情況都使用,會帶來一些弊端:

        • 當(dāng)刪除字段時,不能利用編譯器提示。
        • 當(dāng)一些字段需要額外人工處理時,代碼不易閱讀。
        • 反射賦值,有一定性能損耗。

        總之在業(yè)務(wù)開發(fā)時,還是建議人工編寫,畢竟代碼是給人看的。

        env ??????

        https://github.com/caarlos0/env 這個庫可以將我們的環(huán)境變量轉(zhuǎn)換為一個 struct.

        type?config?struct?{
        ?Home?string?`env:"HOME"`
        }

        func?main()?{
        ?cfg?:=?config{}
        ?if?err?:=?env.Parse(&cfg);?err?!=?nil?{
        ??fmt.Printf("%+v\n",?err)
        ?}

        ?fmt.Printf("%+v\n",?cfg)
        }

        這個在我們打包代碼到不同的運行環(huán)境時非常有用,利用它可以方便的獲取不同環(huán)境變量。

        user_agent ??????

        https://github.com/mssola/user_agent 是一個格式化 user-agent 的小工具。

        當(dāng)我們需要在服務(wù)端收集 user-agen 時可以更快的讀取數(shù)據(jù)。

        func?main()?{
        ????ua?:=?user_agent.New("Mozilla/5.0?(Linux;?U;?Android?2.3.7;?en-us;?Nexus?One?Build/FRF91)?AppleWebKit/533.1?(KHTML,?like?Gecko)?Version/4.0?Mobile?Safari/533.1")

        ????fmt.Printf("%v\n",?ua.Mobile())???//?=>?true
        ????fmt.Printf("%v\n",?ua.Bot())??????//?=>?false
        ????fmt.Printf("%v\n",?ua.Mozilla())??//?=>?"5.0"
        ????fmt.Printf("%v\n",?ua.Model())????//?=>?"Nexus?One"
        ????fmt.Printf("%v\n",?ua.Platform())?//?=>?"Linux"
        ????fmt.Printf("%v\n",?ua.OS())?
        ????}

        phonenumbers ??????

        https://github.com/nyaruka/phonenumbers 手機號碼驗證庫,可以不用自己寫正則表達式了。

        //?parse?our?phone?number
        num,?err?:=?phonenumbers.Parse("6502530000",?"US")
        基礎(chǔ)工具

        接下來是一些基礎(chǔ)工具庫,包含一些主流的存儲的客戶端、中間件等。

        gomonkey ??????????

        github.com/agiledragon/gomonkey 是一個 mock 打樁工具,當(dāng)我們寫單元測試時,需要對一些非接口函數(shù)進行 mock 會比較困難,這時就需要用到它了。

        由于它是修改了調(diào)用對應(yīng)函數(shù)時機器跳轉(zhuǎn)指令,而 CPU 架構(gòu)的不同對應(yīng)的指令也不同,所以在我們使用時還不兼容蘋果的 M1 芯片,不過目前應(yīng)該已經(jīng)兼容了,大家可以試試。

        goconvey ??????????

        https://github.com/smartystreets/goconvey 也是配合單元測試的庫,可以兼容 go test 命令。

        • 提供可視化 web UI。
        • 與 IDE 集成顯示單元覆蓋率。8bc18ebde707ad629986323c021e9415.webp

        dig ??????????

        https://github.com/uber-go/dig 這是一個依賴注入庫,我們這里暫不討論是否應(yīng)該使用依賴注入,至少目前我們使用下來還是有幾個好處:

        • 所有的對象都是單例。
        • 有一個統(tǒng)一的地方管理對象。
        • 使用時直接傳遞對象當(dāng)做參數(shù)進來即可(容器會自動注入)。

        當(dāng)然也有一些不太方便的地方:

        • 不熟悉時,一個對象是如何創(chuàng)建的不清楚。
        • 代碼不是很好理解。

        我們內(nèi)部有自己開發(fā)一個業(yè)務(wù)框架,其中所有的對象都交由 dig 進行管理,使用起來倒也是比較方便。

        cobra ????????

        https://github.com/spf13/cobra是一個功能強大的命令行工具庫,我們用它來實現(xiàn)內(nèi)部的命令行工具,同時也推薦使用 https://github.com/urfave/cli/ 我個人會更習(xí)慣用后者,要簡潔一些。

        BloomRPC ????????

        https://github.com/uw-labs/bloomrpc 一個 gRPC 可視化工具,比起自己寫 gRPC 客戶端的代碼那確實是要簡單許多。

        8098465dcd9d9104a7b0c56c6cd4209a.webp但也有些小問題,比如精度。如果是 int64 超過了 2^56 服務(wù)端拿到的值會發(fā)生錯誤,這點目前還未解決。

        redis ????????

        https://github.com/go-redis/redis/ Redis 客戶端,沒有太多可說的;發(fā)展了許多年,該有的的功能都有了。

        elastic ????????

        https://github.com/olivere/elastic 這也是一個非常成熟的 elasticsearch 庫。

        resty ????????

        https://github.com/go-resty/resty/ ?一個 http client, 使用起來非常簡單:

        //?Create?a?Resty?Client
        client?:=?resty.New()
        resp,?err?:=?client.R().
        ????EnableTrace().
        ????Get("https://httpbin.org/get")

        有點 Python requests 包那味了。

        pulsar-client-go ??????

        Pulsar 官方出品的 go 語言客戶端,相對于 Java 來說其他語言的客戶端幾乎都是后娘養(yǎng)的;功能會比較少,同時更新也沒那么積極;但卻沒得選。

        go-grpc-middleware ??????

        https://github.com/grpc-ecosystem/go-grpc-middleware 官方提供的 gRPC 中間件,可以自己實現(xiàn)內(nèi)部的一些鑒權(quán)、元數(shù)據(jù)、日志等功能。

        go-pilosa ??????

        https://github.com/pilosa/go-pilosa 是一個位圖數(shù)據(jù)庫的客戶端,位圖數(shù)據(jù)庫的場景應(yīng)用比較有限,通常是有標(biāo)簽需求時才會用到;比如求 N 個標(biāo)簽的交并補集;數(shù)據(jù)有一定規(guī)模后運營一定會提相關(guān)需求;可以備著以備不時之需。

        pb ??????

        https://github.com/cheggaaa/pb 一個命令行工具進度條,編寫命令行工具時使用它交互會更優(yōu)雅。

        5b05aac5794a6f20fa6dc9544135acbb.webp總結(jié)

        最后我匯總了一個表格,方便查看:

        名稱類型功能星級
        Gin業(yè)務(wù)開發(fā)HTTP 框架??????????
        GORM業(yè)務(wù)開發(fā)ORM 框架??????????
        errors業(yè)務(wù)開發(fā)異常處理庫??????????
        zorolog業(yè)務(wù)開發(fā)日志庫??????????
        excelize業(yè)務(wù)開發(fā)Excel相關(guān)需求??????????
        now業(yè)務(wù)開發(fā)時間處理?????????
        Decimal業(yè)務(wù)開發(fā)精度處理?????????
        configor業(yè)務(wù)開發(fā)配置文件?????????
        go-cache業(yè)務(wù)開發(fā)本地緩存??????
        copier業(yè)務(wù)開發(fā)數(shù)據(jù)復(fù)制????????
        env業(yè)務(wù)開發(fā)環(huán)境變量????????
        user_agent業(yè)務(wù)開發(fā)讀取 user-agent????????
        phonenumbers業(yè)務(wù)開發(fā)手機號碼驗證????????
        gomonkey基礎(chǔ)工具mock工具?????????
        goconvey基礎(chǔ)工具單測覆蓋率?????????
        dig基礎(chǔ)工具依賴注入?????????
        cobra基礎(chǔ)工具命令行工具???????
        cli基礎(chǔ)工具命令行工具???????
        BloomRPC基礎(chǔ)工具gRPC 調(diào)試客戶端???????
        redis基礎(chǔ)工具Redis 客戶端???????
        elastic基礎(chǔ)工具elasticsearch 客戶端???????
        resty基礎(chǔ)工具http 客戶端???????
        pulsar-client-go基礎(chǔ)工具Pulsar 客戶端??????
        go-grpc-middleware基礎(chǔ)工具gRPC 中間件?????
        go-pilosa基礎(chǔ)工具pilosa 客戶端??????
        pb基礎(chǔ)工具命令行工具進度條??????

        星級評分的規(guī)則主要是看實際使用的頻次。

        最后夾帶一點私貨(其實也談不上) 文中提到了我們內(nèi)部有基于以上庫整合了一個業(yè)務(wù)開發(fā)框架;也基于該框架上線了大大小小10幾個項目,改進空間依然不少,目前還是在快速迭代中。

        大概的用法,入口 main.go:b60c99ba236c40399ea81955ff3f050f.webp4d5551f3ab19be5a8aecd638e3f2d1e8.webp最后截取我在內(nèi)部的分享就概括了整體的思想--引用自公司一司姓同事。

        也許我們內(nèi)部經(jīng)過多次迭代,覺得有能力開放出來給社區(qū)帶來一些幫助時也會嘗試開源;現(xiàn)階段就不嫌丑了。

        這些庫都是我們?nèi)粘i_發(fā)最常用到的,也歡迎大家在評論區(qū)留下你們常用的庫與工具。


        0abcf9a7f827ad624cd7109e859c81f1.webp

        []*T *[]T *[]*T 傻傻分不清楚


        3dd14a30ab62533ef19d6797ba8a124a.webp

        Go 中的 channel 與 Java BlockingQueue 的本質(zhì)區(qū)別


        e22a0af6ba24e39bd7017637f8216f9e.webp

        自帶的 print 函數(shù)居然會報錯?


        f6d68d1ee241188584eda4eb603f9da6.webp

        蜜月行之云南篇(上)


        fba9045e339b8822825a74a180552b1e.webp

        Pulsar:下一代消息引擎真的這么強嗎?



        瀏覽 75
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            午夜黄片 | 97爱 | 黄黄视频在线观看 | 九九精品久久久久久久久无码人妻 | 日韩午夜精品人妻无码一区二区 | 蜜乳在线 | 国产艹b视频 | 干了四年的金毛都没事 | 中文字幕片不卡在线 | 国产精品国产精品国产专区不片 |