Go 包相關
包的作用
Go
語言中的包是原始碼的集合,是一種高階的程式碼複用方案。
在Go
語言中擁有很多自帶的包,如fmt
、os
等。
我們也可以進行一個自定義的包。
定義包
一個檔案只能歸屬於一個包。
如main
舊是一個可執行檔案包,編譯main
包會得到一個可執行檔案,如果是非main
包則不會得到一個可執行檔案。
包的命名不可以和資料夾名字相同,並且不可含有特殊符號。
如下的定義一個test
包。
注意:一個main包不可被其他檔案進行匯入
package test import ( "fmt" ) // F1 是一個公開的方法 func F1(){ fmt.Println("test包中的F1") }
可見性
在包內,如果識別符號首字母為大寫則代表該識別符號是對外可見的。
反之則是該包的私有識別符號。
package test
import (
"fmt"
)
// F1 是一個公開的方法
func F1(){
fmt.Println("test包中的F1")
}
// Person 是一個公開的結構體
type Person struct{
name string // name是一個私有的結構體欄位
}
匯入包
注意事項
匯入包時使用import
關鍵字進行匯入。同時它有一些以下的注意事項:
import匯入語句通常放在檔案開頭包宣告語句的下面。
匯入的包名需要使用雙引號包裹起來,同時包名則是資料夾的名稱。
包名是從$GOPATH/src/後開始計算的,使用/進行路徑分隔。
Go語言中禁止迴圈匯入包。
單行匯入
單行匯入是使用較少的匯入方式,格式如下:
import "包1"
import "包2"
多行匯入
多行匯入使用括號進行包裹,可在一個import
下匯入多個包,格式如下:
import (
"包1"
"包2"
)
別名匯入
我們可以為匯入的包取一個自定義名字,格式如下:
import 別名 "包的路徑"
或者在多行匯入時這樣使用,內建的包會放在上面,自定義或第三方包會放在下面。
import ( "內建包" 別名 "第三方包路徑" )
匿名匯入
匿名匯入的意義在於我們只匯入這個包,但是並不會呼叫其中的某些方法。
如連結資料庫時就會使用到匿名匯入。
匿名匯入的包與其他方式匯入的包一樣都會被編譯到可執行檔案中。
語法如下:
import _ "包的路徑"
示例演示
目錄結構如下:
- bin
- pkg
- src
- yunya.com
- module
- test.go // 這是一個自定義包
- main.go // 啟動檔案
我們想在main.go
中使用test.go
中的功能,則可進行如下的匯入:
package main
import "fmt"
import "yunya.com/module" // 注意,包是所屬資料夾的名稱
func main() {
test.F1()
fmt.Println("執行fmt中的Println")
}
init函式
函式介紹
init()
函式是一個go
檔案作為包時將自動觸發的一個函式(如果沒有該函式則忽略)。
init()
函式沒有引數也沒有返回值, init()
函式在程式執行時自動被呼叫執行,不能在程式碼中主動呼叫它。
如下所示:
test.go
package test
import (
"fmt"
)
// F1 是一個公開的方法
func F1(){
fmt.Println("test包中的F1")
}
// Person 是一個公開的結構體
type Person struct{
name string // name是一個私有的結構體欄位
}
func init(){
fmt.Println("自動執行我啦")
}
當呼叫該包時,自動執行init
,列印結果如下:
package main
import "fmt"
import "yunya.com/module" // 注意,包是所屬資料夾的名稱
func main() {
test.F1()
fmt.Println("執行fmt中的Println")
}
// 自動執行我啦
// test包中的F1
// 執行fmt中的Println
main與init
如果一個go
檔案是一個main
包,同時在其中聲明瞭那麼main()
函式與init()
函式執行誰先誰後呢?
結果如下:
package main // 單獨執行,main包不可被匯入
import (
"fmt"
)
func main() {
fmt.Println("執行main")
}
func init() {
fmt.Println("執行init")
}
// 執行init
// 執行main
執行順序
Go
語言包會從main
包開始檢查其匯入的所有包,每個包中又可能匯入了其他的包。
Go
編譯器由此構建出一個樹狀的包引用關係,再根據引用順序決定編譯順序,依次編譯這些包的程式碼。
在執行時,被最後匯入的包會最先初始化並呼叫其init()
函式, 如下圖示:
多個main
當一個專案下有多個main
時,則不用進行匯入。依次執行即可,在編譯時會自動將其整合成一個可執行檔案。
注意:多個main時需要防止變數衝突的問題,同時多個main中沒有可見性這一說法,由於會整合成一個可執行檔案,所以它們彼此之間都是可見的
目錄結構如下:
- bin
- pkg
- src
- yunya.com
- start.go // 啟動檔案 main包
- s1.go // main包
- s2.go // main包
具體程式碼如下:
// -- start中的內容
package main
import (
"fmt"
)
func main() {
fmt.Println(s1)
fmt.Println(s2)
}
// -- s1中的內容
package main
var s1 = string("s1變數")
// -- s2中的內容
package main
var s2 = string("s2變數")
執行命令時,使用以下命令:
go run start.go s1.go s2.go
或者直接使用以下命令,編譯該資料夾下所有的main
包go
檔案進行整合處理:
go build