Python 程式設計師的 Golang 學習指南(I): Go 之初體驗

Cloudinsight發表於2016-10-12

Authors: startover


Go 語言簡介

Go,又稱 golang,是 Google 開發的一種靜態強型別,編譯型,併發型,並具有垃圾回收功能的程式語言。

Go 語言於2009年11月正式宣佈推出,自2012年釋出1.0,最新穩定版1.7。目前,Go的相關工具和生態已逐漸趨於完善,也不乏重量級專案,如 Docker, Kubernetes, Etcd, InfluxDB 等。

Go 語言能解決什麼樣的問題

同絕大多數通用型程式語言相比,Go 語言更多的是為了解決我們在構建大型伺服器軟體過程中所遇到的軟體工程方面的問題而設計的。乍看上去,這麼講可能會讓人感覺 Go 非常無趣且工業化,但實際上,在設計過程中就著重於清晰和簡潔,以及較高的可組合性,最後得到的反而會是一門使用起來效率高而且很有趣的程式語言,很多程式設計師都會發現,它有極強的表達力而且功能非常強大。

總結為以下幾點:

  • 清晰的依賴關係
  • 清晰的語法
  • 清晰的語義
  • 偏向組合而不是繼承
  • 提供簡單的程式設計模型(垃圾回收、併發)
  • 強大的內建工具(gofmt、godoc、gofix等)

建議有興趣的同學看看 Go在谷歌:以軟體工程為目的的語言設計

Go 語言相對 Python 有哪些優勢

這裡引用一段知乎上某大牛的回答,如下:

  • 部署簡單。Go 編譯生成的是一個靜態可執行檔案,除了 glibc 外沒有其他外部依賴。這讓部署變得異常方便:目標機器上只需要一個基礎的系統和必要的管理、監控工具,完全不需要操心應用所需的各種包、庫的依賴關係,大大減輕了維護的負擔。這和 Python 有著巨大的區別。由於歷史的原因,Python 的部署工具生態相當混亂【比如 setuptools, distutils, pip, buildout 的不同適用場合以及相容性問題】。官方 PyPI 源又經常出問題,需要搭建私有映象,而維護這個映象又要花費不少時間和精力。

  • 併發性好。Goroutine 和 channel 使得編寫高併發的服務端軟體變得相當容易,很多情況下完全不需要考慮鎖機制以及由此帶來的各種問題。單個 Go 應用也能有效的利用多個 CPU 核,並行執行的效能好。這和 Python 也是天壤之比。多執行緒和多程式的服務端程式編寫起來並不簡單,而且由於全域性鎖 GIL 的原因,多執行緒的 Python 程式並不能有效利用多核,只能用多程式的方式部署;如果用標準庫裡的 multiprocessing 包又會對監控和管理造成不少的挑戰【我們用的 supervisor 管理程式,對 fork 支援不好】。部署 Python 應用的時候通常是每個 CPU 核部署一個應用,這會造成不少資源的浪費,比如假設某個 Python 應用啟動後需要佔用 100MB 記憶體,而伺服器有 32 個 CPU 核,那麼留一個核給系統、執行 31 個應用副本就要浪費 3GB 的記憶體資源。

  • 良好的語言設計。從學術的角度講 Go 語言其實非常平庸,不支援許多高階的語言特性;但從工程的角度講,Go 的設計是非常優秀的:規範足夠簡單靈活,有其他語言基礎的程式設計師都能迅速上手。更重要的是 Go 自帶完善的工具鏈,大大提高了團隊協作的一致性。比如 gofmt 自動排版 Go 程式碼,很大程度上杜絕了不同人寫的程式碼排版風格不一致的問題。把編輯器配置成在編輯存檔的時候自動執行 gofmt,這樣在編寫程式碼的時候可以隨意擺放位置,存檔的時候自動變成正確排版的程式碼。此外還有 gofix, govet 等非常有用的工具。

  • 執行效能好。雖然不如 C 和 Java,但通常比原生 Python 應用還是高一個數量級的,適合編寫一些瓶頸業務。記憶體佔用也非常省。

從個人對 Golang 的初步使用來說,體驗還是相當不錯的,但是也有下面幾點需要注意:

  • 駝峰式命名風格(依據首字母大小寫來決定其是否能被其他包引用),但我更喜歡 Python 的小寫字母加下劃線命名風格。

  • 沒有好用的包管理器,Golang 官方也沒有推薦最佳的包管理方案,目前公認的比較好用的有 Godeps, Govendor 及 Glide,而 Python 的包管理器 pip 已形成自己的一套標準。

  • 多行字串的變數宣告需要用反引號(`),Python 裡是三個雙引號("""),參考http://stackoverflow.com/questions/7933460/how-do-you-write-multiline-strings-in-go

  • Golang 中的型別匹配是很嚴格的,不同的型別之間通常需要手動轉換,所以在字串拼接時往往需要對整型進行顯式轉換,如 fmt.Println("num: " + strconv.Itoa(1))

  • Golang 語言語法裡的語法糖並不多,如在 Python 中很流行的 map, reduce, range 等,在 Golang 裡都沒有得到支援。

另外,推薦閱讀 Golang 新手開發者要注意的陷阱和常見錯誤

學習資料推薦

建議先把 Go 的官方文件過一遍,主要有以下幾項:

官方文件看完後,基本也算入門了,這時候可以看看 Go 的示例程式碼,或者去 Project Euler 刷刷題。

當然也可以去知乎看看大牛們都是如何學習的,連結 https://www.zhihu.com/question/23486344

總結

雖然 Go 有很多被詬病的地方,比如 GC 和對錯誤的處理方式,但沒有任何語言是完美的,從實用角度來講,Go 有著不輸於 Python 的開發效率,完善的第三方工具,以及強大的社群支援,這些就足夠了。

相關連結:
https://golang.org/doc/
https://talks.golang.org/2012/splash.article
https://www.zhihu.com/question/21409296
https://www.zhihu.com/question/23486344
http://stackoverflow.com/questions/7933460/how-do-you-write-multiline-strings-in-go
http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/
http://www.oschina.net/translate/go-at-google-language-design-in-the-service-of-software-engineering


本文章為 Cloudinsight 技術團隊工程師原創,更多技術文章可訪問 Cloudinsight 技術部落格Cloudinsight 為視覺化系統監控工具,涵蓋 Windows、Linux 作業系統,用 Golang 開發的 Cloudinsight Agent 正式開源了,歡迎 fork,Github:https://github.com/cloudinsight/cloudinsight-agent

golang-for-pythonistas 系列持續更新中,歡迎關注~

相關文章