12个必不可少的Go软件包和库
Go是一種令人贊嘆的語言,具有很大的發展動力,并且專注于簡單性。 這種方法在其標準庫中很明顯,該庫提供了所有基本要素,但不多。
幸運的是,Go擁有一個充滿活力的社區,該社區創建并共享了許多第三方庫。 在本教程中,我將向您介紹Go的12個最佳軟件包和庫。 其中一些具有相對狹窄的范圍,可以添加到任何項目中,而另一些則是大型項目,您可以將其合并到大規模,大規模的分布式系統中。
太棒了
在深入探究庫本身之前,讓我向您介紹Awesome Go ,這是一個非常活躍且精心策劃的Go庫和其他資源列表。 您應該不時訪問并檢查新功能。
1. Golang-Set
Go具有數組,切片和地圖,但是沒有固定的數據結構。 您可以使用布爾映射來模擬集合,但最好是具有正確的操作和語義的實際數據類型。 這是golang-set的來源。這是創建新集合,添加項目和測試成員資格的基本示例:
package mainimport ("fmt""github.com/deckarep/golang-set" )func main() {basicColors := mapset.NewSet()basicColors.Add("Red")basicColors.Add("Blue")basicColors.Add("Green")if basicColors.Contains("Green") {fmt.Println("Yay! 'Green' is a basic color")} else {fmt.Println("What a disappointment! 'Green' is not a basic color")}if basicColors.Contains("Yellow") {fmt.Println("Yay! 'Yellow' is a basic color")} else {fmt.Println("What a disappointment! 'Yellow' is not a basic color")} }Output:Yay! 'Green' is a basic color What a disappointment! 'Yellow' is not a basic color請注意,程序包名稱為“ mapset”。 除了基礎知識外,您還執行所有設置操作,例如并集,交集和差。 您還可以遍歷設置值:
package mainimport ("fmt""github.com/deckarep/golang-set" )func main() {basicColors := mapset.NewSet()basicColors.Add("Red")basicColors.Add("Blue")basicColors.Add("Green")otherColors := mapset.NewSetFromSlice([]interface{}{"Orange", "Yellow", "Indigo", "Violet"})rainbowColors := basicColors.Union(otherColors)for color := range rainbowColors.Iterator().C {fmt.Println(color)} }2.顏色
讓我們繼續顏色主題。 在編寫命令行程序時,使用顏色突出顯示重要消息或區分錯誤,成功和警告很有用。
顏色包為您的程序添加一些顏色提供了一種簡便的方法(請參閱我在那里做的事情?)。 它使用ANSII轉義碼,也支持Windows! 這是一個簡單的示例:
package mainimport ("github.com/fatih/color" )func main() {color.Red("Roses are red")color.Blue("Violets are blue") }顏色包支持將顏色與背景色,粗體或斜體等樣式混合,以及將顏色與非顏色輸出混合使用。
package mainimport ("github.com/fatih/color""fmt" )func main() {minion := color.New(color.FgBlack).Add(color.BgYellow).Add(color.Bold)minion.Println("Minion says: banana!!!!!!")m := minion.PrintlnFunc()m("I want another banana!!!!!")slantedRed := color.New(color.FgRed, color.BgWhite, color.Italic).SprintFunc()fmt.Println("I've made a huge", slantedRed("mistake")) }彩色包裝還有其他有用的功能。 繼續探索更多。
3.現在
現在,這是一個非常簡單的程序包,它為標準時間程序包提供了方便的包裝,并使在當前時間周圍輕松處理各種日期和時間構造成為可能。
例如,您可以獲取當前分鐘的開始時間或最接近當前時間的星期日的結束時間。 這是使用“現在”的方法:
package mainimport ("github.com/jinzhu/now""fmt" )func main() {fmt.Println("All the beginnings...")fmt.Println(now.BeginningOfMinute())fmt.Println(now.BeginningOfHour())fmt.Println(now.BeginningOfDay())fmt.Println(now.BeginningOfWeek())fmt.Println(now.BeginningOfMonth())fmt.Println(now.BeginningOfQuarter())fmt.Println(now.BeginningOfYear())}Output:All the beginnings... 2017-06-04 16:59:00 -0700 PDT 2017-06-04 16:00:00 -0700 PDT 2017-06-04 00:00:00 -0700 PDT 2017-06-04 00:00:00 -0700 PDT 2017-06-01 00:00:00 -0700 PDT 2017-04-01 00:00:00 -0700 PDT 2016-12-31 23:00:00 -0800 PST您還可以解析時間,甚至添加自己的格式(這將需要更新已知格式)。 Now類型嵌入了time.Time ,因此您可以直接在Now對象上使用所有time.Time方法。
4.根
gen工具會為您生成代碼,特別是類型識別代碼,它試圖緩解Go中沒有模板或泛型的空白。
您用特殊注釋注釋類型,然后gen生成包含在項目中的源文件。 沒有運行時魔術。 讓我們來看一個例子。 這是帶注釋的類型。
// +gen slice:"Where,Count,GroupBy[int]" type Person struct {Name stringAge int }運行gen (確保它在您的路徑中)會生成person_slice.go :
// Generated by: gen // TypeWriter: slice // Directive: +gen on Personpackage main// PersonSlice is a slice of type Person. Use it where you would use []Person. type PersonSlice []Person// Where returns a new PersonSlice whose elements return true for func. See: http://clipperhouse.github.io/gen/#Where func (rcv PersonSlice) Where(fn func(Person) bool) (result PersonSlice) {for _, v := range rcv {if fn(v) {result = append(result, v)}}return result }// Count gives the number elements of PersonSlice that return true for the passed func. See: http://clipperhouse.github.io/gen/#Count func (rcv PersonSlice) Count(fn func(Person) bool) (result int) {for _, v := range rcv {if fn(v) {result++}}return }// GroupByInt groups elements into a map keyed by int. See: http://clipperhouse.github.io/gen/#GroupBy func (rcv PersonSlice) GroupByInt(fn func(Person) int) map[int]PersonSlice {result := make(map[int]PersonSlice)for _, v := range rcv {key := fn(v)result[key] = append(result[key], v)}return result }該代碼提供了類似于LINQ的方法來對PersonSlice類型進行操作。 它很容易理解,并且有很好的文檔記錄。
使用方法如下。 在主要功能中,定義了PersonSlice 。 age()函數從其Person參數中選擇年齡字段。 生成的GroupByInt()函數采用age()函數并從按年齡分組的切片中返回人員(34是吉姆,但23既有簡又有凱爾)。
package mainimport ("fmt" )// +gen slice:"Where,Count,GroupBy[int]" type Person struct {Name stringAge int }func age(p Person) int {return p.Age }func main() {people := PersonSlice {{"Jim", 34},{"Jane", 23},{"Kyle", 23},}groupedByAge := people.GroupByInt(age)fmt.Println(groupedByAge) }Output:map[34:[{Jim 34}] 23:[{Jane 23} {Kyle 23}]]5. Gorm
Go以其斯巴達性格而聞名。 數據庫編程也不例外。 Go最受歡迎的數據庫庫是相當底層的。 Gorm通過以下功能將對象關系映射世界帶到了Go:
- 關聯(有一個,有很多,屬于,很多對很多,多態)
- 回調(創建/保存/更新/刪除/查找之前/之后)
- 預加載(急切加載)
- 交易次數
- 復合主鍵
- SQL生成器
- 自動遷移
- 記錄儀
- 可擴展,基于GORM回調編寫插件
但這并不能涵蓋所有內容。 如果您來自Python,請不要指望SQLAlchemy魔術。 對于更多花哨的東西,您必須將其降至更低的水平。 這是一個如何將Gorm與sqlite一起使用的示例。 請注意Product結構中的嵌入式gorm.Model 。
package mainimport ("github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/sqlite" )type Product struct {gorm.ModelCode stringPrice uint }func main() {db, err := gorm.Open("sqlite3", "test.db")if err != nil {panic("failed to connect database")}defer db.Close()// Migrate the schemadb.AutoMigrate(&Product{})// Createdb.Create(&Product{Code: "L1212", Price: 1000})// Readvar product Productdb.First(&product, 1) // find product with id 1db.First(&product, "code = ?", "L1212")// Update - update product's price to 2000db.Model(&product).Update("Price", 2000)// Delete - delete productdb.Delete(&product)6.鵝
使用關系數據庫時,最重要的任務之一就是管理模式。 在某些組織中,修改數據庫架構被認為是“小小的”改變。 goose軟件包使您可以執行模式更改,甚至在需要時進行數據遷移。 您可以goose up goose down走來走去。 不過請注意您的數據,并確保它不會丟失或損壞。
Goose通過對模式進行版本控制并使用與每個模式相對應的遷移文件來工作。 遷移文件可以是SQL命令或Go命令。 這是添加新表的SQL遷移文件的示例:
-- +goose Up CREATE TABLE person (id int NOT NULL,name text,age int,PRIMARY KEY(id) );-- +goose Down DROP TABLE person;-- +goose up和-- +goose down注釋告訴goose如何升級或降級架構。
7.滑翔
Glide是Go的軟件包管理器。 在單個GOPATH ,您可能有許多具有相互依賴的程序。 解決方案是讓每個程序管理其自己的程序包依賴關系供應商目錄。 滑行可以幫助完成此任務。
以下是滑行的功能:
- 支持版本控制包,包括語義版本2.0.0支持。
- 支持別名包(例如,使用github forks)。
- 無需修改導入語句。
- 使用所有Go工具。
- 支持Go支持的所有VCS工具(git,bzr,hg,svn)。
- 支持自定義本地和全局插件。
- 存儲庫緩存和數據緩存可提高性能。
- 平整依賴性,解決版本差異并避免多次包含軟件包。
- 按需或在版本控制系統中按需管理和安裝依賴項。
依賴項存儲在glide.yaml中 ,glide提供了幾個命令來管理依賴項:
create, init Initialize a new project, creating a glide.yaml fileconfig-wizard, cw Wizard that makes optional suggestions to improve config in a glide.yaml file.get Install one or more packages into `vendor/` and add dependency to glide.yaml.remove, rm Remove a package from the glide.yaml file, and regenerate the lock file.import Import files from other dependency management systems.name Print the name of this project.novendor, nv List all non-vendor paths in a directory.rebuild Rebuild ('go build') the dependenciesinstall, i Install a project's dependenciesupdate, up Update a project's dependenciestree (Deprecated) Tree prints the dependencies of this project as a tree.list List prints all dependencies that the present code references.info Info prints information about this projectcache-clear, cc Clears the Glide cache.about Learn about Glidemirror Manage mirrorshelp, h Shows a list of commands or help for one command8.銀杏
銀杏是一個BDD(行為驅動開發)測試框架。 它使您能夠以類似于英語的語法編寫測試,并允許較少的技術人員檢查測試(及其輸出)并驗證它們是否符合業務需求。
一些開發人員也喜歡這種風格的測試規范。 它與Go的內置測試包集成在一起,通常與Gomega結合使用。 這是一個銀杏+ Gomega測試的例子:
actual, err := foo() Ω(err).Should(BeNil()) Ω(actual).ShouldNot(BeNil()) Ω(actual.result).Should(Equal(100))9.等
Etcd是可靠的分布式鍵值存儲。 服務器在Go中實現,而Go客戶端通過gRPC與之交互。
它著重于以下方面:
- 簡單:定義明確,面向用戶的API(gRPC)。
- 安全:具有可選客戶端證書身份驗證的自動TLS。
- 快速:基準10,000次寫入/秒。
- 可靠:使用Raft正確分發。
這是連接到服務器,設置值并獲取它的一個示例,包括超時和清除。
func test_get() {cli, err := clientv3.New(clientv3.Config{Endpoints: endpoints,DialTimeout: dialTimeout,})if err != nil {log.Fatal(err)}defer cli.Close()_, err = cli.Put(context.TODO(), "foo", "bar")if err != nil {log.Fatal(err)}ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)resp, err := cli.Get(ctx, "foo")cancel()if err != nil {log.Fatal(err)}for _, ev := range resp.Kvs {fmt.Printf("%s : %s\n", ev.Key, ev.Value)}// Output: foo : bar }10. NSQ
NSQ是一個很棒的分布式隊列。 我已經成功地將其用作大型分布式系統的主要構建塊。 以下是其一些功能:
- 支持無SPOF的分布式拓撲。
- 水平可擴展(沒有代理,可以無縫地將更多節點添加到集群)。
- 基于低延遲推送的消息傳遞(性能)。
- 組合負載平衡和多播樣式的消息路由。
- 在流(高吞吐量)和面向工作(低吞吐量)的工作負載下都可以使用Excel。
- 主要在內存中(超出高水位標記的消息透明地保存在磁盤上)。
- 供消費者用來查找生產者的運行時發現服務(nsqlookupd)。
- 傳輸層安全性(TLS)。
- 數據格式不可知。
- 很少有依賴項(易于部署)和合理,有界的默認配置。
- 支持任何語言的客戶端庫的簡單TCP協議。
- 用于統計信息,管理操作和生產者的HTTP接口(無需發布客戶端庫)。
- 與statsd集成以進行實時檢測。
- 強大的群集管理界面(nsqadmin)。
這是將消息發布到NSQ的方法(避免了錯誤處理):
package mainimport ("github.com/bitly/go-nsq" )func main() {config := nsq.NewConfig()p, _ := nsq.NewProducer("127.0.0.1:4150", config)p.Publish("topic", []byte("message"))p.Stop() }這里是如何消費:
package mainimport ("sync""fmt""github.com/bitly/go-nsq" )func main() {wg := &sync.WaitGroup{}wg.Add(1)config := nsq.NewConfig()q, _ := nsq.NewConsumer("topic", "channel", config)handler := nsq.HandlerFunc(func(message *nsq.Message) error {fmt.Printf("Got a message: %v", message)wg.Done()return nil})q.AddHandler(handler)q.ConnectToNSQD("127.0.0.1:4150")wg.Wait() }11.碼頭工人
Docker現在是家喻戶曉的名字(如果您的家人大多是DevOps人)。 您可能不知道Docker是在Go中實現的。 您通常不會在代碼中使用Docker,但這是一個重要的項目,應該被認為是一個非常成功和流行的Go項目。
12. Kubernetes
Kubernetes是面向云原生應用程序的開源容器編排平臺。 這是Go中實現的另一個怪物分布式系統。 我最近寫了一本書,叫做《 掌握Kubernetes》 ,其中詳細介紹了Kubernetes的最高級方面。 從Go開發人員的角度來看,Kubernetes非常靈活,您可以通過插件對其進行擴展和自定義。
結論
Go是一門很棒的語言。 它的設計理念是成為一種簡單易懂的語言。 它的標準庫不如Python之類的其他語言那么全面。
Go社區得到了加強,您可以在程序中使用許多高質量的庫。 在本文中,我介紹了12個庫。 我鼓勵您在進入并從頭實現所有內容之前,先尋找其他庫。
翻譯自: https://code.tutsplus.com/tutorials/12-indispensable-go-packages-and-libraries--cms-29008
總結
以上是生活随笔為你收集整理的12个必不可少的Go软件包和库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JAVA】通过ISBN一键获取书籍信息
- 下一篇: 记录一次GoLang软件debug模式F