項目中要不要使用 Go?我是這麼思考的

2020-04-28   Go語言中文網

更多Go資訊,歡迎微信公眾號「Go語言中文網」關注我們,可領全套Go資料,每天學習 Go 語言

我最近決定在一個新項目中使用 GoLang 來實現一組增刪改查的 API。在此之前,我較為熟悉 Java,Groovy,了解一些 Python。

我大部分的經驗都是使用 Java 或者 Groovy 加上 Spring Boot。這讓我感到有些無聊,所以為什麼不來學點兒東西找找樂子呢?

要求

以下是一些要求。

  • 設計並實現領域數據模型
  • 實現增刪改查 API
  • 在後端使用 Mongo 資料庫
  • 必須有 Swagger 文檔 API 定義並且能方便的用多種語言生成客戶端
  • 運行在 Docker 容器中
  • 能被部署在 Kubernetes 中

非功能性要求

  • 需要能很容易的調用其它語言的 API
  • 需要能夠快速疊代(可能要突破常規)
  • 必須有單元測試

加分項

  • 保守的內存消耗
    • 這對於當我想在一個內存受限的環境中(如一個 512 MB 內存的樹莓派)運行程序時,是很重要的。
  • 要有趣也要有學習體驗

使用的模塊和庫

作用模塊訪問資料庫mongo-go-drive路由go-chiREST API JSON Patch( 譯者註:RFC6902[1] 和 RFC7396[2])json-patch單元測試testifySwagger API 定義go-swagger

優點

Go 語言與 C 和 Java 十分的相像。有 C 和 Java 的基礎能很容易的熟練掌握 Go 語言,完成一個入門項目。

我特別喜歡 Go 代碼的簡單明了。

公平來說,我也喜歡樣板代碼儘可能少的,備受好評的框架。我就十分喜歡 Java 11+ 或者 Groovy 與 Spring Boot,Spring Data,Lombok 項目,可能還有 Spring Data REST 的聯合使用。當然,有時候 Spring Boot Data REST 的魔法有點兒過猶不及了。

Go 的 'defer' 關鍵字可以說是我最喜歡的特性之一了。推遲一些操作直到函數退出才執行這一特性,在關閉資源並記錄函數退出動作的日誌方面十分有用。

不同點與不合適點

錯誤處理有點兒繁瑣。

錯誤處理對於 Java 背景的人來說有些不同。我發現在 Go 中它需要更明確。

在 Java 中,一個方法能拋出一個異常,也可以捕獲一個或多個異常,忽略它們(這樣做可能是錯誤的),或者重新拋出給調用者來處理。Go 需要使用先調用方法,然後判斷是否有錯誤發生這種模式。我們可以討論下這樣做好不好。

我發現對於 Go 的錯誤檢測和傳遞需要一段時間來適應而且覺得有點繁瑣,但這樣肯定是能行的。

// 我經常在代碼中看到這樣的模式
obj1, err := doohickey.doSomething(someArg)
if err !=nil {
    log.Println("doohickey.doSomething got error error: ", err)
    return
}
obj2, err2 := widget.doSomethingElse(otherArg)
if err2 !=nil {
    log.Println("Widget doSomethingElse returned error: ", err2)
    return
}
//...

JSON 響應類型以及映射到結構體

對於 Go,JSON 和 靜態類型,我發現 Go 在如何處理動態 JSON 和將其解析為結構體方面有些笨拙和令人困惑。

這在 Groovy 和 Python 中相當容易,他們完全可以動態的把 JSON 轉換成其他東西的映射。

在 Go 中,將 JSON 反序列化為一個結構並將其序列化回來,這與其他語言中的做法並沒有本質上的不同。

成熟度進展

實際上,我在這方面並沒有發現它有什麼不好的。正相反,我發現了一些期待的地方。因為 Go 仍然是一門相對比較新的語言,在一些領域它正在迎頭趕上。

Go 依賴和版本化模塊庫

因為以前使用過依賴管理和構建工具,如 Java 的 Gradle 和 Maven,自然而然的我就想 Go 有同種水平的依賴管理。

在我寫本文時,GoLang 1.13[3] 支持谷歌的模塊代理,文檔上是這樣說的:

從 Go 1.13 開始,go 命令在默認情況下將使用由 Google 運行的 Go 模塊鏡像、 Go 檢驗和資料庫來進行模塊的下載與認證。參看 https://proxy.golang.org/privac[4] 來了解有關這些服務的隱私信息,參看 go 命令文檔[5] 了解怎麼停止使用這些服務或者使用另外的服務的詳細配置。如果你依賴於一個不公開的模塊,參見 環境配置文檔[6]

結束語

令人驚訝的是,很容易地就可以掌握 GoLang 到實際生產的程度。我覺得它令人愉快而且很有趣。增強 REST API,精鍊數據模型,生成 Swagger 文檔和創建單元測試都是很流行並舒服的體驗。

基於這次的經歷,我越發的想學習 GoLang 了。

參考資料

[1]

RFC6902: http://tools.ietf.org/html/rfc6902

[2]

RFC7396: https://tools.ietf.org/html/rfc7396

[3]

GoLang 1.13: https://golang.org/doc/go1.13

[4]

https://proxy.golang.org/privac: https://proxy.golang.org/privacy

[5]

go 命令文檔: https://golang.org/cmd/go/#hdr-Module_downloading_and_verification

[6]

環境配置文檔: https://golang.org/cmd/go/#hdr-Module_configuration_for_non_public_modules