Go 程式設計教學:套件 (Package)

PUBLISHED ON DEC 10, 2017 — PROGRAMMING

套件將一些相關的函式或物件集中,以易於分享的形式包裝起來。另外,對套件開發者來說,套件提供命名空間 (namespace) 和可視度 (scope)。所謂的標準函式庫就是一群預先和 Go 編譯環境一同發布的套件,此外,我們也可以透過其他第三方 (third-party) 套件來增強 Go 的功能。

去中心化的套件分享模式

先前的程式語言,像是 Perl 或 Python,由該語言的社群提供一個大型的套件庫 (package repository),由社群開發者將套件上傳到此套件庫,像是 CPAN (Perl) 或 PyPI (Python) 等。現在的套件開發流程,受到 Git 和 Mercurial 等版本控制軟體的影響,開發者依自己的喜好,將套件放在 GitHub 或 Bitbucket 或 GitLab 等站台,再透過 Git 和 Mercurial 等工具下載。也就是說,Go 社群不額外維護自己的套件庫,而將套件庫的責任委外給 GitHub 等專業網站。

Go 套件管理工具會依需求自動呼叫以下四種版本控制軟體:

例如,下載 gotk3 (Go 的 GTK+3 binding):

$ go get github.com/gotk3/gotk3/gtk

Go 套件管理工具會自動偵測該套件使用 Git,並呼叫 Git 來下載該套件。

Go 套件

Go 套件就是含有 Go 程式碼的專案 (project),而專案以資料夾為單位。Go 專案不需要額外的設定檔或樣板程式碼,直接將 Go 程式碼放在專案內即可;管理的方式是透過內建的 Go 套件管理工具。Go 專案以扁平化的方式放置專案,直接將程式碼放在說明文件的同一層目錄即可。

對於較大的專案,也可以再將程式碼細分在數個子專案中,每個子專案各自放在獨立的子目錄即可。像是前述的 gotk3 專案就根據其對應的函式庫將專案再分為數個部分,讀者可以觀察一下 gotk3 專案的架構即可略知一二。

在 Go 程式碼中,一定要為套件命名,這個命名起著命名空間的作用,不同的套件名稱可以減少程式碼的衝突。執行檔一定是位於 package main 之下,而函式庫則會採用其他的名稱。通常 Go 套件會採用簡短的縮寫或單詞,像是 bufio (buffered io) 或是 fmt (format) 等。由於社群套件通常會放在 GitHub 等原始碼管理站台,專案網址在某種程度上也成了套件名稱的一部分,程式設計者通常不用太擔心套件名稱的衝突。

另外,Go 套件也起著封裝 (encapsulation) 的作用,在 Go 語言中,以小寫開頭的變數或函式會私有化,無法從外部存取,但套件內的測試程式仍然可以存取這些私有的程式。減少不當的公開變數和方法對於軟體維護也有所助益。

引入套件

引用套件會使用 import。標準函式庫會隨著 Go 編譯器等一併安裝,不需另外安裝;對於第三方套件,則需先行以 Go 工具安裝後再引用。先前內建的 Go 工具會將套件安裝到 GOPATH 所在的位置;目前因應一些開發者需求,有一些第三方工具會仿照 Node 的模式,在資料夾內直接以 vendor 資料夾儲存第三方套件;目前 Go 官方團隊也開始嘗試性地加入此功能。目前有幾個工具支援第三方套件管理:

目前來說,depgovendor 開發較活躍,可考慮使用;而 glide 開發者建議 Go 程式設計者轉到 dep,該專案之後可能不再開發新特性。

撰寫套件文件

站在軟體工程的觀點,若套件能有相關的說明文件,讓套件使用者易於查詢,對於推廣套件也有所幫助。為了節省製作文件的時間,許多程式語言都有製作套件文件的工具,而 Go 也內建了撰寫套件文件的工具。說實在的,很多程式設計者懶得寫套件文件;即使寫了,也會忘記隨程式碼更新說明文字。為了簡化撰寫套件的工作,Go 團隊在這一點上下了一些工夫;程式設計者只要在函式或變數上以註解撰寫說明文字即可,至於函式的變數和回傳值等資訊會自動由程式碼中讀取,最後再輸出成有一定質感的網頁。實例如下:

// Add sums up two numbers.
func Add(a int, b int) int {
    return a + b
}

另外,按照 Go 的慣例,會另外以 doc.go 做為整個套件的說明文件,在該檔案中不放入任何實際的程式碼。

comments powered by Disqus