<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>

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

          共 7725字,需瀏覽 16分鐘

           ·

          2021-12-02 10:28

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

          因?yàn)槲覀€(gè)人大概前五年時(shí)間寫(xiě)的是 Java ,中途寫(xiě)過(guò)一年多的 Python,所以剛接觸到 Go 時(shí)的感覺(jué)如下圖:

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

          寫(xiě)到現(xiàn)在的感覺(jué)就是:

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

          這里我主要將這些庫(kù)分為兩類(lèi):

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

          業(yè)務(wù)開(kāi)發(fā)

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

          Gin ??????????

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

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

          GORM ??????????

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

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

          errors ??????????

          Go 語(yǔ)言自身提供的錯(cuò)誤處理比較簡(jiǎn)單,https://github.com/pkg/errors 提供了更強(qiáng)大的功能,比如:

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

          常用的有以下 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 里的日志打印庫(kù)非常多,日志在日常開(kāi)發(fā)中最好就是存在感低;也就是說(shuō)性能強(qiáng)(不能影響到業(yè)務(wù)代碼)、使用 API 簡(jiǎn)單。

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

          excelize

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

          now ????????

          https://github.com/jinzhu/now 是一個(gè)時(shí)間工具庫(kù):

          • 獲取當(dāng)前的年月日、時(shí)分秒。
          • 不同時(shí)區(qū)支持。
          • 最后一周、最后一個(gè)月等。
          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ù)上需要精度計(jì)算時(shí) 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 的類(lèi)型,數(shù)據(jù)庫(kù)對(duì)應(yīng)的也是 decimal ,這樣使用起來(lái)時(shí)會(huì)更方便。

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

          configor ????????

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

          go-cache ??????

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

          ?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 看名字就知道這是一個(gè)數(shù)據(jù)復(fù)制的庫(kù),與 Java 中的 BeanUtils.copy() 類(lèi)似;可以將兩個(gè)字段相同但對(duì)象不同的 ?struct 進(jìn)行數(shù)據(jù)復(fù)制,也支持深拷貝。

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

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

          但也要注意不要什么情況都使用,會(huì)帶來(lái)一些弊端:

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

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

          env ??????

          https://github.com/caarlos0/env 這個(gè)庫(kù)可以將我們的環(huán)境變量轉(zhuǎn)換為一個(gè) 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)
          }

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

          user_agent ??????

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

          當(dāng)我們需要在服務(wù)端收集 user-agen 時(shí)可以更快的讀取數(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 手機(jī)號(hào)碼驗(yàn)證庫(kù),可以不用自己寫(xiě)正則表達(dá)式了。

          //?parse?our?phone?number
          num,?err?:=?phonenumbers.Parse("6502530000",?"US")

          基礎(chǔ)工具

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

          gomonkey ??????????

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

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

          goconvey ??????????

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

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

          dig ??????????

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

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

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

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

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

          cobra ????????

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

          BloomRPC ????????

          https://github.com/uw-labs/bloomrpc 一個(gè) gRPC 可視化工具,比起自己寫(xiě) gRPC 客戶端的代碼那確實(shí)是要簡(jiǎn)單許多。

          但也有些小問(wèn)題,比如精度。如果是 int64 超過(guò)了 2^56 服務(wù)端拿到的值會(huì)發(fā)生錯(cuò)誤,這點(diǎn)目前還未解決。

          redis ????????

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

          elastic ????????

          https://github.com/olivere/elastic 這也是一個(gè)非常成熟的 elasticsearch 庫(kù)。

          resty ????????

          https://github.com/go-resty/resty/ ?一個(gè) http client, 使用起來(lái)非常簡(jiǎn)單:

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

          有點(diǎn) Python requests 包那味了。

          pulsar-client-go ??????

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

          go-grpc-middleware ??????

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

          go-pilosa ??????

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

          pb ??????

          https://github.com/cheggaaa/pb 一個(gè)命令行工具進(jìn)度條,編寫(xiě)命令行工具時(shí)使用它交互會(huì)更優(yōu)雅。

          總結(jié)

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

          名稱類(lèi)型功能星級(jí)
          Gin業(yè)務(wù)開(kāi)發(fā)HTTP 框架??????????
          GORM業(yè)務(wù)開(kāi)發(fā)ORM 框架??????????
          errors業(yè)務(wù)開(kāi)發(fā)異常處理庫(kù)??????????
          zorolog業(yè)務(wù)開(kāi)發(fā)日志庫(kù)??????????
          excelize業(yè)務(wù)開(kāi)發(fā)Excel相關(guān)需求??????????
          now業(yè)務(wù)開(kāi)發(fā)時(shí)間處理?????????
          Decimal業(yè)務(wù)開(kāi)發(fā)精度處理?????????
          configor業(yè)務(wù)開(kāi)發(fā)配置文件?????????
          go-cache業(yè)務(wù)開(kāi)發(fā)本地緩存??????
          copier業(yè)務(wù)開(kāi)發(fā)數(shù)據(jù)復(fù)制????????
          env業(yè)務(wù)開(kāi)發(fā)環(huán)境變量????????
          user_agent業(yè)務(wù)開(kāi)發(fā)讀取 user-agent????????
          phonenumbers業(yè)務(wù)開(kāi)發(fā)手機(jī)號(hào)碼驗(yàn)證????????
          gomonkey基礎(chǔ)工具mock工具?????????
          goconvey基礎(chǔ)工具單測(cè)覆蓋率?????????
          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ǔ)工具命令行工具進(jìn)度條??????

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

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

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

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

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


          瀏覽 42
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  婷婷精品秘 进入 | 俺去也一二三区 | 中国婬乱a—级毛片多女 | 日韩人妻天天躁夜夜摸 | 五月天最新网址 |