1 . 為什麼選擇Go
近年來,大量的博都在誇讚Go優於Java / Python / C / Pearl,不過題主說了不要引戰,我們就主要聚焦Go本身——Go無所不能。
Go可以確保我們的工具箱可在所有平臺和所有硬體上編譯;Go使用非常簡單軟體包管理解決方案,讓我們體會到什麼是“得心應手”和非常便攜;Go提供記憶體管理和垃圾收集功能;提供了本機二進位制可執行檔案,沒有依賴項,不需要VM;不需要外部伺服器,因為都已整合;幾乎沒有關鍵字,同時無需一種標準的格式化程式碼的方法。
1)為軟體工程而構建
Go幾乎可以在任何機器上進行編譯,因此我們不但可以使用它建立完整的Web應用,也可以構建工具來清理傳入的資料以進行處理。
2)就是這樣的簡單
對於瞭解程式設計或其掌握一定程式語言的人,學習Go最多需要幾個小時。只要你掌握Go的一定技巧之後,就可以開始動手編寫了。
3)執行速度非常快
在正則表示式測試(regex-redux)中,Go執行大概3.55秒,而Java運行了5.58。 Go程式需要102行程式碼,而Java大概70行;的確,Go比Java程式碼量大一點,但是考慮到Go在執行速度上如此輕易的擊敗Java這樣一個主流程式語言,我們可能也別無他求了。
4)成為大量專案的首選
如題主所講,許多開源專案和私有專案正在轉向使用Go語言開發,並且它作為微服務和Web的標準語言變得越來越有用。可以預測,未來它可能還會取代效能較低的解決方案,如Java和C。
2 . Go為併發而設計
讓我們看一下goroutines,本質上是併發函式,它們會在程式的其餘部分完成時執行。換句話說,我們可以啟動goroutine,使其執行,並在其和成千上萬的goroutines在後臺執行時繼續執行。
網路超時?不用擔心,當主迴圈繼續時,你的goroutine將對其進行管理;資料庫完全失敗?你的goroutine對此很清楚,你仍舊可以從容解決此資料庫問題。
看一個簡單的例子:
package mainimport ( "fmt" "time")func hello() { fmt.Println("Hello world goroutine")}func main() { go hello() time.Sleep(1 * time.Second) fmt.Println("main function")}
該main功能的工作原理就像它在C中一樣,main觸發一個goroutine,表示該go關鍵字-called hello()。該程式短暫停頓,然後繼續;如果hello()函式中發生任何事情,該main函式將不會注意到。重要的是工作已經完成。
當main例程喚醒並觸發Println,該程式結束。該hello()函式可以是任何東西(資料呼叫、transaction,佇列條目),並且它將在程式其餘部分執行時執行。
如果想要看到它的實際效果,可以去道Go Playground上檢視,
https://play.golang.org/p/U9ZZuSql8-play.golang.org
你能看到goroutines是如何工作的。
對於Web應用,goroutine可以讓我們執行併發作業,同時避免障礙,例如,如果我們正在等待資料輸入,即使使用者正在鍵入,goroutine也會觸發以提供預填充的文字,換句話說,即使併發程序花費的時間比預期的長,你的程式仍將繼續執行。
最棒的是,goroutine很便宜,因此Go變得更快。
GoLangBot的創始人Naveen Ramanathan曾在在部落格上寫道:
“ Goroutines被多路複用到更少數量的OS執行緒。” “在具有數千個Goroutine的程式中,可能只有一個執行緒。如果該執行緒中的任何Goroutine阻塞(例如,等待使用者輸入),則會建立另一個OS執行緒,並將其餘的Goroutines移至新的OS執行緒。所有這些都由執行時處理,作為程式設計師,我們從這些複雜的細節中抽象出來,並獲得了乾淨的API以併發使用。”
3 . 5個有用的Go模組
最後Golang具有出色的文件,很容易擴充套件,它還有一些非常有用的Go模組,分享5個2021你必須知道的Go語言模組:
-Gen
Gen是實際為你生成程式碼的工具,它旨在為你的types提供類似泛型的功能。
安裝模組
執行以下命令:
go get github.com/clipperhouse/gen
要使用此模組,首先要建立一個新的Go專案並定義一個型別:
// +gen slice:"Where,Count,GroupBy[string]"type MyType struct {}
在命令列中,只需鍵入:
gen
你應該看到一個名為的新檔案mytype_slice.go。
-Go Kit
Go Kit是用於Go相關微服務的標準庫,它提供對專用微服務的支援。
安裝模組
執行以下命令:
go get github.com/go-kit/kit
我們將建立一個新的Go專案並建立一個新模型,輸入以下程式碼行:
// model.gopackage articleimport ( "time")// Article modeltype Article struct { ID string `json:"id"` Username string `json:"username"` Content string `json:"content"` Text string `json:"title"` CreatedOn time.Time `json:"created_on"`}
現在我們需要建立我們的服務:
// service.gopackage articleimport ( "context")// ArticleService for Articlestype TodoService interface { GetAllForUser(ctx context.Context, username string) ([]Article, error) GetByID(ctx context.Context, id string) (Article, error) Add(ctx context.Context, article Article) (Article, error) Update(ctx context.Context, id string, article Article) error Delete(ctx context.Context, id string) error}
要獲取有關如何實施此服務的更多資訊,建議您使用GoKit訪問
Sinnott's Blogdanielsinnott.com
-Fuzzy
這是一個Go庫,它提供針對檔名和程式碼符號最佳化的模糊字串匹配。
安裝模組
執行以下命令:
go get github.com/jroimartin/gocui
在Fuzzy的GitHub頁面上,給出了以下示例程式碼:
package mainimport ( "fmt""sahilm/fuzzy")func main() { const bold = "\033[1m%s\033[0m" pattern := "mnr" data := []string{"game.cpp", "moduleNameResolver.ts", "my name is_Ramsey"}matches := fuzzy.Find(pattern, data)for _, match := range matches { for i := 0; i < len(match.Str); i++ { if contains(i, match.MatchedIndexes) { fmt.Print(fmt.Sprintf(bold, string(match.Str[i]))) } else { fmt.Print(string(match.Str[i])) } } fmt.Println() }}func contains(needle int, haystack []int) bool { for _, i := range haystack { if needle == i { return true } } return false}
有關詳細文件,可以去到
https://godoc.org/github.com/sahilm/fuzzygodoc.org
-Etcd
Etcd是可靠的分散式鍵值儲存。
安裝模組
執行以下命令:
go get github.com/etcd-io/etcd
使用建立客戶端clientv3.New
// expect dial time-out on ipv4 blackhole_, err := clientv3.New(clientv3.Config{ Endpoints: []string{"http://254.0.0.1:12345"}, DialTimeout: 2 * time.Second,})// etcd clientv3 >= v3.2.10, grpc/grpc-go >= v1.7.3if err == context.DeadlineExceeded { // handle errors}// etcd clientv3 <= v3.2.9, grpc/grpc-go <= v1.2.1if err == grpc.ErrClientConnTimeout { // handle errors}cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"}, DialTimeout: 5 * time.Second,})if err != nil { // handle error!}defer cli.Close()
-Ginkgo
Ginkgo是一個行為驅動的開發測試框架,你可以使用類似於英文的語法來編寫測試。
安裝模組
執行以下命令
go get github.com/onsi/ginkgo/ginkgo
建立一個新的Go專案。例如,在測試代碼中匯入gomega軟體包
Gomegaonsi.github.io
package books_testGomegapackage books_testimport ( . "onsi/ginkgo" . "onsi/gomega" "testing")func TestBooks(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Books Suite")}