午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

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

 菌心說 2021-11-02
文章圖片1

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

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

文章圖片2

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

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

文章圖片3

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

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

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

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

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

Gin ??????????

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

當然和它配套的 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 是一個時間工具庫:

  • 獲取當前的年月日、時分秒。
  • 不同時區(qū)支持。
  • 最后一周、最后一個月等。
import 'github.com/jinzhu/now'time.Now() // 2013-11-18 17:51:49.123456789 Monnow.BeginningOfMinute() // 2013-11-18 17:51:00 Monnow.BeginningOfHour() // 2013-11-18 17:00:00 Monnow.BeginningOfDay() // 2013-11-18 00:00:00 Monnow.BeginningOfWeek() // 2013-11-17 00:00:00 Sunnow.BeginningOfMonth() // 2013-11-01 00:00:00 Frinow.BeginningOfQuarter() // 2013-10-01 00:00:00 Tuenow.BeginningOfYear() // 2013-01-01 00:00:00 Tuenow.EndOfMinute() // 2013-11-18 17:51:59.999999999 Monnow.EndOfHour() // 2013-11-18 17:59:59.999999999 Monnow.EndOfDay() // 2013-11-18 23:59:59.999999999 Monnow.EndOfWeek() // 2013-11-23 23:59:59.999999999 Satnow.EndOfMonth() // 2013-11-30 23:59:59.999999999 Satnow.EndOfQuarter() // 2013-12-31 23:59:59.999999999 Tuenow.EndOfYear() // 2013-12-31 23:59:59.999999999 Tuenow.WeekStartDay = time.Monday // Set Monday as first day, default is Sundaynow.EndOfWeek() // 2013-11-24 23:59:59.999999999 Sun

Decimal ????????

當業(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ù)復制的庫,與 Java 中的 BeanUtils.copy() 類似;可以將兩個字段相同但對象不同的 struct 進行數(shù)據(jù)復制,也支持深拷貝。

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

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

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

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

總之在業(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 的小工具。

當我們需要在服務(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 numbernum, err := phonenumbers.Parse('6502530000', 'US')

基礎(chǔ)工具

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

gomonkey ??????????

github.com/agiledragon/gomonkey 是一個 mock 打樁工具,當我們寫單元測試時,需要對一些非接口函數(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 集成顯示單元覆蓋率。

dig ??????????

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

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

當然也有一些不太方便的地方:

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

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

cobra ????????

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

BloomRPC ????????

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

文章圖片4

但也有些小問題,比如精度。如果是 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 Clientclient := resty.New()resp, err := client.R(). EnableTrace(). Get('https:///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)用比較有限,通常是有標簽需求時才會用到;比如求 N 個標簽的交并補集;數(shù)據(jù)有一定規(guī)模后運營一定會提相關(guān)需求;可以備著以備不時之需。

pb ??????

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

文章圖片5

總結(jié)

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

文章圖片6

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

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

大概的用法,入口 main.go:

文章圖片7
文章圖片8

最后截取我在內(nèi)部的分享就概括了整體的思想--引用自公司一司姓同事。

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

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

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多