Go 程式設計教學:使用考量

PUBLISHED ON AUG 20, 2017 — PROGRAMMING

    在上一篇文章中,我們簡單地介紹 Go 的特性,相信讀者已經對 Go 有一些初步的了解。接下來,筆者會在本篇文章中討論 Go 的長短處以及 Go 的使用情境等,讓讀者可以進一步考量是否要在下一個專案中使用 Go,畢竟,當專案成長到成千上萬行的程式碼後,重寫的代價是相當可觀的。

    首先,筆者要提醒各位讀者,雖然 Go 語言相當簡潔易學,寫起來近於腳本語言,但 Go 語言並不是完美無缺的。基本上,Go 語言承襲 C 語言的思想,再加上輕量級物件 (lightweight objects) 及垃圾回收 (garbage collections)。在這樣的思維下,Go 語言刻意地在語法上保持簡單化、最小化,缺乏許多現代語言常見的特性,筆者列出一些實例:

    • 缺乏泛型 (generics),這是最常討論的議題
    • 缺乏函式重載 (function overloading)
    • 缺乏運算子重載 (operator overloading)
    • 缺乏列舉 (enumration)
    • 強制程式碼風格

    要注意的是,缺乏這些特性不會導致我們無法撰寫程式,只是要用其他的手法達成我們的目的,我們會在後續的文章中逐一探討;畢竟,語法特性只是撰寫程式的過程中所用的一些手段,最重要的還是最終的成品 (product)。如果我們去比較一些主流語言,可以發現,Go 在思維上比較接近 C 和 Java,儘量減少花俏的語法魔術,而使用樸實、明確的程式碼風格,讓程式維護者可以很清楚地了解這段程式的目的,而不需要去記憶某些特殊的內隱性語法。

    註:這樣樸實的特性多用 verbose 來形容。

    Go 是一門通用型語言,但是,Go 不見得在所有的領域都吃得開,我們會就不同使用情境,分別探討 Go 是否適用。筆者列出一些常見的使用情境:

    • 終端機程式 (console application)
    • 圖形介面程式 (graphic user interface application)
    • 網頁程式 (web application) 和其他伺服器程式 (server application)
    • 行動程式 (mobile application)
    • 電腦遊戲 (computer game)
    • 元件 (component),即其他高階語言的延伸模組 (extension module)

    使用 Go 撰寫終端機程式,可說是相當好的選擇;雖然 Go 的效能不若 C,但 Go 程式碼、標準函式庫、編譯環境都是跨平台的,對於終端機程式來說,效能往往不是最重要的考量;此外,Go 在字串處理也比 C 高階,更加快程式的撰寫。不過,終端機程式不是目前主流的程式類型,通常是程式設計者或專業人士才會使用這種程式:如果有這方面需求,可以考慮用 Go 取代 C 來撰寫程式。

    理論上,搭配良好的圖形使用者函式庫,Go 也有機會成為另一個圖形介面程式語言。不過,這類程式不是 Google 首要考量的目標,目前僅能依賴一些社群套件,像是 GTK+ 或 Qt 的 Go binding 等。除此之外,還有一些有潛力的選項,像是 wxGo 和 ui 專案等。目前來說,由於 Go binding 的 API 較原生 API 落後,用 Go 寫圖形介面程式仍需審慎評估,至少要瀏覽一下該套件的 API,以了解是否能夠符合自己的需求,以免跳下去後才發現不符自己的期望。

    Google 是以網路和網頁程式起家,可想而知,網頁程式和其他伺服器程式可說是 Go 的強項,也最符合 Google 本身的利益。觀察一下 Go 標準函式庫即可發現 Go 對伺服器程式的支援相當地完善,除此之外也有許多社群套件,目前已有一些商業公司將 Go 用於網頁程式和伺服器程式。這類應該應該是目前 Go 最適合的開發項目 (sweet spot)。

    雖然 Go 專案裡有一項和行動軟體相關的專案,但是,這項專案一直保持在實驗性質 (experimental)。另外,由於 Google 和 Oracle 間因 Java 而產生的訴訟,Google 對 Android 需要採取一定的策略,除了繼續使用 Java 外,採用 Kotlin (一個新興 Java 平台語言) 做為另一個開發 Android 程式的新選擇,或是使用 Dart 加上 Flutter 這個新的平台;如果在加上 Go mobile,我們就有四個開發 Android 程式的方案。說實在的,過多重覆的選擇反而造成社群資源分散,Google 也需要不同團隊去維護這些資源。現階段來說,使用 Go 不是最佳選擇。

    由於 Go 的特性,Go 不太適合即時運算程式,目前以 Go 撰寫的電腦遊戲也沒有很多。雖然有一些以 Go 撰寫的遊戲引擎 (game engine),像是 Ebiten (2D)、Azul3D (3D) 等,但這些遊戲引擎畢竟不是市場主流,如果某一天這些引擎未繼續開發,自己的專案就形同斷頭了。如果遊戲是要營利,應該要用更主流的開發工具;反之,如果不以營利為考量,利用這些引擎撰寫小型電腦遊戲其實也不失為學習程式設計的好方法。

    Go 在 1.5 版加入了輸出 C 函式庫的功能;理論上,透過這個功能,我們可以用 Go 代替 C (或 C++),為其他高階語言,像是 Python 或 Ruby 等,撰寫延伸模組;然而,經筆者實測,發現問題多多:最重要的議題在於 Go 程式無法輸出結構 (struct),使得我們幾乎無法撰寫實用的 C 函式庫;替代的方式是在函式間傳遞 JSON 或 XML 等字串,但這等於每次函式呼叫都要進行字串解析,往往使得效能低下。目前 Go 社群對這個議題的討論度不高,看來這不是 Go 主要的發展目標。

    經過本文的介紹,讀者應該對於 Go 的使用情境有更多了解,對於是否要在自己的下一個專案中使用 Go 更有信心。在下一篇文章中,我們會介紹如何安裝 Go,以做為開發 Go 程式的準備。

    comments powered by Disqus