Go 程式設計教學:建立專案

PUBLISHED ON SEP 2, 2017 — PROGRAMMING

在上一篇文章中,我們介紹如何建立 Go 開發環境,相信讀者都能順利建置開發環境。接下來,在這篇文章中,我們會實際動手撰寫 Go 程式及建立 Go 專案。

Hello World

在這裡,我們以經典的「Hello World」範例來說明如何撰寫 Go 程式。首先,建立文字檔案 hello.go,加入以下內容:

package main
 
import (
    "fmt"
)
 
func main() {
    fmt.Println("Hello, World")
}

先不用擔心這些程式碼的意思,下文會說明。接著,執行該程式:

$ go run hello.go
Hello, World

也可以將程式碼編譯成執行檔後再執行:

$ go build hello.go
$ ./hello
Hello, World

這就是我們第一個 Go 程式。

Go 專案

在一開始練習語法時,筆者建議都先使用單一檔案即可,以簡化學習過程。不過,隨著專案需求,我們會將 Go 程式碼整理在專案 (project) 中。所謂的 Go 專案,就是將 Go 程式碼集中在同一個資料夾中,以利管理,使用版本控制軟體管理專案程式碼時,也需要將程式碼集中在同一個資料夾或其子目錄中。在預設情形下,單一的 Go 專案採取扁平式的結構來安排程式,但其實仍然可以用巢狀架構來安排專案。

Go 的專案可分為兩種:

  • 執行檔 (executable)
  • 函式庫 (library)

前者是可執行的電腦程式;後者則無法直接執行,而是預先寫好一些程式碼,待其他執行檔呼叫。Go 沒有制式的專案設定檔,也沒有內建的專案產生器,雖然有些 IDE 可以協助我們建立 Go 專案,筆者建議各位讀者至少要手動建立幾個專案,以熟悉建立 Go 專案的流程。傳統的編譯語言中,C 和 C++ 要撰寫 Make 或 CMake 設定檔,Java 要用 Maven 或 Gradle 管埋專案,相較起來,Go 在專案管理上算是簡化不少。

在這裡,我們以經典的「Hello World」範例來說明如何建立 Go 專案。首先,在 GOPATH 的 src/ 目錄下建立 hello 資料夾,接著,在該資料夾中建立 main.go 檔案。過程以 GNU/Linux 指令展示如下:

$ cd $GOPATH/src
$ mkdir hello
$ cd hello
$ touch main.go

Go 沒有強制規定程式碼的名稱,使用 main.go 僅是便於記憶。接著,撰寫和先前相同的 Hello World 程式碼。接著,執行該程式:

$ go run main.go
Hello, World

也可以將程式碼編譯成執行檔後再執行:

$ go build
$ ./hello
Hello, World

Go 的專案相對簡單,使用內建的工具即可管理,不像其他的語言需要一些樣板程式碼或設定檔。

再訪 Hello World

我們再看一次 Hello World 程式,這次加上程式碼註解 (comment) 以利閱讀:

// Declare package name, mandatory for all Go programs
package main
 
// Import required packages.
import (
    "fmt"
)
 
// Our main program.
func main() {
    fmt.Println("Hello, World")
}

Go 程式有三個部分:

  • 套件宣告
  • 引入套件
  • 主函式

所有 Go 程式在一開始時都要宣告套件名稱,宣告套件使用 package 關鍵字 (keyword)。執行檔一定要宣告為 main 套件,函式庫則會使用其他名稱。一開始學習程式時,都是寫運行在終端機的終端機程式 (console application),皆會宣告 package main。

接著,若程式需要引入其他套件,則會使用 import 關鍵字引入套件,在本例中,我們僅引入 fmt 套件,若有需要,可以引入更多套件。在撰寫程式時,我們不會從頭開始撰寫所有的功能,而會引用他人寫好的套件,以節省開發程式的時間。在一個典型的專案中,通常只有 15-20% 的功能是重頭開始寫,其他的功能多由外部套件引入,可知使用外部套件的重要性。Go 開發環境即包含許多立即可用的套件,這些官方提供的套件稱為標準函式庫;除此之外,還可以下載第三方套件以節省開發時間。

雖然許多 Go 套件都可以自由從網路上下載,但使用套件時仍然要注意套件的所使用的授權。雖然一開始自己練習寫的小程式通常也不會有事,但最好還是養成觀看授權的習慣。初學者可能會懷疑,每用一個套件就要看一堆法律條文?由於自由軟體運動盛行,有許多專家預先制定一些常見的自由軟體授權,只要知道授權名稱即可。如果只是要使用該套件,不對該套件修改的話,像是 public domain、MIT、BSD、Apache、LGPL 等授權都可以放心使用;如果用 GPL 授權套件則要公開原始碼,宜慎重考慮;至於其他的授權,則依各位授權條款而定。

Go 執行檔會有一個特定的進入點,即 main 函式;宣告函式使用 func 關鍵字,main 函式是一個特別的函式,每個執行檔只能有一個 main 函式,而且 main 函式的寫法是固定的,如本例所展示的程式碼。初學者不會寫函式也不用太擔心,就把 main 函式當成制式的樣版程式碼即可。

對於初學者來說,先會撰寫能順利執行的程式即可,不用太擔心一些瑣碎的細節。接下來的內容,是給有程式設計經驗的學習者看的,如果看不懂也不用太在意,先學會寫 Go 程式,之後再回頭閱讀本文即可。

再談專案

Go 在設計時,就有將一些軟體工程的因素考慮進去,所以,Go 在套件宣告上設置了一些限制。理論上,同一個專案不會既是執行檔,又是函式庫,所以,在同一個目錄底下的程式碼都要宣告成同一個套件名稱。另外,Go 採扁平式的程式碼管理,通常專案下不會另外設置子目錄,而會將專案程式碼直接放在該專案的根目錄。

不過,有時候,專案會比較複雜,例如,gotk3 專案 (GTK 3 的 Go binding) 內部其實是由數個函式庫組成,通通放在同一個目錄內並不適當。我們現在舉一個例子,假設我們有一個專案,該專案包括核心功能、圖形使用者介面程式、網頁程式三個部分,放在三個子目錄會較合適,如以下的例子:

$ cd $GOPATH/src/myapp
$ tree
myapp
├── core
├── myapp
└── web

其中三個子專案的套件名稱宣告如下:

  • core:為函式庫,套件可宣告為 lib 或其他名稱
  • web:為網頁程式,為執行檔,套件宣告為 main
  • myapp:為圖形使用者介面程式,為執行檔,套件宣告為 main

因目錄名稱會變成執行檔名稱,所以在建立終端機程式或圖形使用者程式時,不要使用 bin/ 做為目錄名稱,而要使用執行檔的名字做為目錄名稱。在我們這個例子中,假設只有一個核心函式庫,實際上,可以隨需求切出更多函式庫,這會隨著專案需求而有所不同。

當我們這樣安排專案時,若沒有將專案放在 GOPATH 下,可能會無法編譯程式。這樣的設計可能會讓初學者混淆,但其實這些都只是一些檔案路徑的規畫方式,實際建立過一兩次就會有印象。

經過本文介紹,讀者應該可以開始撰寫 Go 程式。接著,我們會進入 Go 程式設計的一些細節,在下一篇文章中,我們會從最基本的變數 (variable) 和資料型別 (data type) 開始談起。

comments powered by Disqus