過去的一兩週裏,被公司的大佬安利了 Go,用來寫一個代碼、架構分析和自動化重構的工具。經過這麼一週對於 Go 語言的實戰,我算是有底氣來寫一篇文章來介紹(吐槽)一下 Go 語言。

優點 1:跨平臺支持(交叉編譯)

對於習慣了創造輪子的我而言,起先我覺得使用 Go,又或者是其它語言並沒有多大的區別。直到我看到了,大佬在 macOS 下構建出了 Windows、GNU/Linux 和 macOS 等系統的可執行文件的時候,我覺得 NBility現在,我已經把 Go 列爲了 我的 CLI 工具的首選語言

如果你和我一樣,嘗試過開發一系列的跨平臺應用,那麼就會心累於跨平臺開發。如:

  1. 使用 Electron 開發跨平臺應用 。除了開發機器,你還需要一個目標操作系統(如 Windows),以及對應的開發套件(Git、Node.js、Python 等)你才能完成目標操作系統上的構建。
  2. 使用 Java 開發 GUI 應用 。我需要在目標機器上配置 Java 環境,才能運行 jar 包。雖然大部分操作系統已經安裝有了 Java 環境,但是誰還會用它來開發 GUI 應用。
  3. 使用JavaScript / TypeScript 開發 CLI 工具 。嗯,我需要先安裝有一個 Node.js 或者是 Deno,才能運行起我的代碼,還有對應的 Node.js 的版本管理工具。
  4. 使用 Shell 來編寫 CLI 。不好意思,我還沒學會怎麼編寫 Windows 上的 BAT 工具。
  5. ……

當然了,有了 Docker 上面的都是問題,不過你還得先安裝一下 Docker。從這種角度上來說,它和我們使用的 Cordova、React Native、Flutter 相近,只是 Go 更高級一些。因爲前三者目前都不能在 Windows 上編譯出 iOS 應用。而對於 Go 來說,你只需要運行:

GOOS=windows GOARCH=amd64 go build fanta_cli.go

你就能得到一份在目標操作系統上的可執行文件。其中的 $GOARCH 是指目標平臺(編譯後的目標平臺)的處理器架構(386、amd64、arm), $GOOS 是指目標平臺(編譯後的目標平臺)的操作系統(darwin、freebsd、linux、windows)

根據官方的 syslist.go 顯示,它支持這麼一些操作系統和處理器架構:

const goosList = "aix android darwin dragonfly freebsd hurd illumos js linux nacl netbsd openbsd plan9 solaris windows zos "
const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv riscv64 s390 s390x sparc sparc64 wasm "

是的,你可以嘗試使用 Go 來玩轉 WebAssembly 了。

優點 2:部署簡單

使用 Go 語言編寫應用時,你的目標是一個可執行的二進制文件,只需要直接 blabla 就可以運行了。

而,如果你想使用一個在 GitHub 運行的軟件時,你也可以直接運行命令來獲取,就可以直接構建了,如:

go get github.com/phodal/coca

理想情況下,就可以獲得一個可執行的 coca 命令。不過,我這個項目由於使用的是相對路徑,導入有一點問題。

優點 3:原生支持併發

還沒體會到,我先去玩 WebAssembly。

缺點 1:依賴管理

Go 有依賴管理,哦,不 Go 沒有依賴管理。

go dep
go vendor
go modules

嗯,感覺一下,我要這麼引用自己項目中的依賴:

import (
    . "github.com/phodal/coca/refactor/move_class"
    . "github.com/phodal/coca/refactor/rename"
    . "github.com/phodal/coca/refactor/unused"
)

Java 有包依賴衝突,JavaScript 有依賴地獄。但是 Python 和 Go 官方一直沒能解決好依賴問題。

缺點 2:語法設計

好吧, 這個問題每個語言都有,Go 語言最麻煩的是去構建一個函數,因爲 Go 沒有構建函數。所以,你需要這麼去寫你的類:

type RemoveUnusedImportApp struct {
  ...
}

var nodes []JMoveStruct

func (j *RemoveUnusedImportApp) Analysis() { {
    ...
}

但是用起來嘛,也不方便,我還是習慣 New 一下,然後直接調用:

func NewRemoveUnusedImportApp(config string, pPath string) *RemoveUnusedImportApp {
    return &RemoveUnusedImportApp{}
}

其它的語法還都好, 還好。

其它

好吧,我知道 Go 還有其它優點,如性能更好,但是這都是相對來說的。除非你的語言庫裏只有一種語言,這纔會成爲你所謂的優點。

沒有銀彈。

相關文章