Golang Package 初學者指南
文章推薦指數: 80 %
基本上來說,package 不過是Go 工作區中包含一個或多個Go 原始檔案或其他Go package 的目錄。
... 上面的package 宣告必須是Go 原始檔案中的第一行程式碼。
GolangPackage初學者指南
2019-11-12
約6307字/需35分鐘閱讀
原文:CalliCoder—AbeginnersguidetoPackagesinGolang
Go旨在鼓勵良好的軟體工程實踐。
高品質軟體的指導原則之一是DRY原則:Don’tRepeatYourself,這意味著你永遠不應重複撰寫相同的程式碼。
你應該重複使用並儘可能建立在現有程式碼上。
允許程式碼重複使用的最基本的建構區塊是函數。
Package是程式碼可重複使用性的下一步。
他們可幫助你將相關的Go原始檔組織到同一單元中,使他們模組化、可重複使用和可維護。
在本文中,你將學到如何將Go程式碼組織到可重複使用的package中,如何匯入package,如何將函數、型別或變數匯出到外部package,以及如何安裝第三方package。
讓我們開始吧!
Go工作區及程式碼組織在學習Gopackage之前,了解Go程式碼在所謂的Go工作區中的組織方式非常重要。
請查看以下文章,以複習有關Go組織程式碼的概念:
安裝、設定Golang的GOPATH和Go工作區
GoPackage基本上來說,package不過是Go工作區中包含一個或多個Go原始檔案或其他Gopackage的目錄。
每個Go原始檔案都隸屬於一個package。
我們使用以下語法將原始檔案宣告為package的一部分:
package
Go原始檔案中定義的所有函數、型別和變數都會成為所宣告package的一部分。
你可以選擇將package中定義的成員匯出到外部package,或保持其私有化在相同package。
其他package可以匯入並使用從package中匯出的函數或型別。
讓我們來看個範例:到目前為止,我們在本系列教學中幾乎會看到所有程式碼都包含以下這行:
import"fmt"
fmt是一個核心函式庫,包含格式化和列印輸出或從各種I/O來源讀取輸入等相關的功能。
它匯出如Println()、Printf()、Scanf()等函數,以供其他package重複使用。
以這種方式封裝功能具有以下優點:
它減少了命名衝突。
你可以在不同的package中使用相同的函數名稱。
這讓我們的函數名稱簡短明瞭。
它將相關程式碼組織在一起,以便更輕鬆地找到要重複使用的程式碼。
它僅需要重新編譯程式實際上有更改的一小部分,進而加速了編譯過程。
儘管我們使用了fmtpackage,但我們不需要在每次修改我們的程式時重新編譯它。
mainpackage和main()函數Go程式從mainpackage開始執行。
這是一個特殊的package,用於想要執行的程式。
按照慣例,可執行程式(有mainpackage的程式)稱為指令。
其他則簡稱為Package。
main()函數是一個特殊的函數,它是可執行程式的進入點。
讓我們來看一個Go的可執行程式範例:
//Packagedeclaration
packagemain
//Importingpackages
import(
"fmt"
"time"
"math"
"math/rand"
)
funcmain(){
//FindingtheMaxoftwonumbers
fmt.Println(math.Max(73.15,92.46))
//Calculatethesquarerootofanumber
fmt.Println(math.Sqrt(225))
//Printingthevalueof`𝜋`
fmt.Println(math.Pi)
//Epochtimeinmilliseconds
epoch:=time.Now().Unix()
fmt.Println(epoch)
//Generatingarandomintegerbetween0to100
rand.Seed(epoch)
fmt.Println(rand.Intn(100))
}
$gorunmain.go
#Output
92.46
15
3.141592653589793
1538045386
40
匯入PackageGo中有兩種匯入package的方法:
//Multipleimportstatements
import"fmt"
import"time"
import"math"
import"math/rand"
//Factoredimportstatements
import(
"fmt"
"time"
"math"
"math/rand"
)
Go的慣例是:_package的名稱與匯入路徑的最後一個元素相同_。
舉例來說,匯入為math/rand的package的名稱為rand。
它是透過math/rand路徑匯入的,因為它是mathpackage中的巢狀子目錄。
匯出與未匯出的名稱
以大寫字母開頭的所有內容(變數、型別或函數)都會被匯出,並可被外部package看見。
任何不以大寫字母開頭的內容都不會被匯出,並且僅在同一package中可見。
匯入package時,只能存取其匯出的名稱。
packagemain
import(
"fmt"
"math"
)
funcmain(){
//MaxInt64isanexportedname
fmt.Println("Maxvalueofint64:",int64(math.MaxInt64))
//Phiisanexportedname
fmt.Println("ValueofPhi(ϕ):",math.Phi)
//pistartswithasmallletter,soitisnotexported
fmt.Println("ValueofPi(𝜋):",math.pi)
}
#Output
./exported_names.go:16:38:cannotrefertounexportednamemath.pi
./exported_names.go:16:38:undefined:math.pi
要修正以上錯誤,需要將math.pi更改為math.Pi。
建立和管理自訂Package到目前為止,我們只有在mainpackage中撰寫程式碼,並使用從Go核心函式庫匯入的功能。
讓我們建立一個Go專案範例,該專案具有多個自訂package以及一堆原始碼檔案,並了解相同的package宣告、匯入和匯出概念如何套用在自訂package。
這是我們在Go工作區內組織專案的方式:
src資料夾包含我們的Go專案,該專案位於名為example的git儲存庫中。
bin和pkg資料夾分別包含可執行檔和package檔案。
他們在我們安裝程式時由Go工具自動產生。
讓我們逐一查看程式中的每個原始檔案中的程式碼:
numbers/prime.gopackagenumbers
import"math"
//Checksifanumberisprimeornot
funcIsPrime(numint)bool{
fori:=2;i<=int(math.Floor(math.Sqrt(float64(num))));i++{
ifnum%i==0{
returnfalse
}
}
returnnum>1
}
strings/reverse.gopackagestrings
//Reversesastring
/*
SincestringsinGoareimmutable,wefirstconvertthestringtoamutablearrayofrunes([]rune),
performthereverseoperationonthat,andthenre-casttoastring.
*/
funcReverse(sstring)string{
runes:=[]rune(s)
reversedRunes:=reverseRunes(runes)
returnstring(reversedRunes)
}
strings/reverse_runes.gopackagestrings
//Reversesanarrayofrunes
//Thisfunctionisnotexported(Itisonlyvisibleinsidethe`strings`package)
funcreverseRunes(r[]rune)[]rune{
fori,j:=0,len(r)-1;i
延伸文章資訊
- 1Golang 使用外部package - 菜鳥工程師肉豬
Go使用外部的package。 本篇參考官方教學的Call code in an external package。 外部package就是其他人寫好的程式,類似Java的函式庫/套件(libr...
- 2Package 使用多個套件之前必須要懂的包 - iT 邦幫忙
使用import package,Go會先在$GOROOT/src下尋找指定的package。 若找不到就往$GOPATH/src目錄下尋找。 找不到就會報出編譯錯誤。 package main...
- 3Go 套件管理
在〈來個Hello, World〉已經稍微瞭解了 package 與 GOPATH 的關係,原始碼會是在 GOPATH 中設定的目錄之src 中,並有著對照於 package 設定名稱之目錄包括...
- 4golang 之import 和package 的使用- SegmentFault 思否
golang 使用包package 来管理定义模块,可以使用import 关键字来导入使用。 如果导入的是go 自带的包,则会去安装目录$GOROOT/src 按包路径加载, ...
- 5[Golang] Modules and Packages | PJCHENder 未整理筆記
How to Write Go Code @ golang. ... 如果套件是在module 中,go import package 的路徑會是 module path 加上 subdirec...