在Go語言中,可以透過import語句來導入包,導入的包名使用雙引號包圍,包名是從GOPATH開始計算的路徑,使用“/”進行路徑分隔。使用import導入套件有兩種基本格式:1、單行導入語法「import "bao1" import "bao2"」;2、多行導入語法「import("bao1" "bao2" …)」。
本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。
Go語言import導入套件-在程式碼中使用其他的程式碼
可以在一個Go語言原始檔包宣告語句之後,其它非導入宣告語句之前,包含零到多個導入包聲明語句。每個導入聲明可以單獨指定一個導入路徑,也可以透過圓括號同時導入多個導入路徑。若要引用其他套件的標識符,可以使用 import 關鍵字,匯入的套件名稱使用雙引號包圍,套件名稱是從 GOPATH 開始計算的路徑,使用/進行路徑分隔。
預設導入的寫法
導入有兩種基本格式,即單行導入和多行導入,兩種導入方法的導入程式碼效果是一致的。
1) 單行導入
單行導入格式如下:
import "包1" import "包2"
2) 多行導入
當多行導入時,包名在import 中的順序不影響導入效果,格式如下:
import( "包1" "包2" … )
導入包後自訂引用的包名
如果我們想同時導入兩個有著名字相同的包,例如math/rand 包和crypto/rand 包,那麼導入聲明必須至少為一個同名包指定一個新的包名以避免衝突。這叫做導入包的重命名。
import ( "crypto/rand" mrand "math/rand" // 将名称替换为mrand避免冲突 )
匯入套件的重新命名只會影響目前的來源檔案。其它的來源檔案如果導入了相同的包,可以用導入包原本預設的名字或重新命名為另一個完全不同的名字。
導入套件重新命名是一個有用的特性,它不僅僅只是為了解決名字衝突。如果匯入的一個套件名稱很笨重,特別是在一些自動產生的程式碼中,這時候用一個簡短名稱會比較方便。選擇用簡短名稱重命名導入包時候最好統一,以避免包名混亂。選擇另一個套件名稱還可以幫助避免和本地普通變數名稱產生衝突。例如,如果檔案中已經有了一個名為 path 的變量,那麼我們可以將"path"標準套件重新命名為 pathpkg。
每個導入宣告語句都明確指定了目前套件和被導入套件之間的依賴關係。如果遇到套件循環導入的情況,Go語言的建置工具將會報告錯誤。
匿名導入套件-只導入套件但不使用包內類型和數值
如果只希望導入包,而不使用任何套件內的結構和類型,也不呼叫套件內的任何函數時,可以使用匿名導入包,格式如下:
import ( _ "path/to/package" )
其中,path/to/package 表示要導入的包名,下畫線_表示匿名導入包。
匿名導入的套件與其他方式導入套件一樣會讓導入包編譯到可執行檔中,同時,導入包也會觸發 init() 函數呼叫。
套件在程式啟動前的初始化入口:init
#在某些需求的設計上需要在程式啟動時統一呼叫程式引用到的所有套件的初始化函數,如果需要透過開發者手動呼叫這些初始化函數,那麼這個過程可能會發生錯誤或遺漏。我們希望在被引用的套件內部,由包的編寫者獲得程式碼啟動的通知,在程式啟動時做一些自己包內程式碼的初始化工作。
例如,為了提高數學庫計算三角函數的執行效率,可以在程式啟動時,將三角函數的值提前在記憶體中建成索引表,外部程式透過查表的方式迅速獲得三角函數的值。但是三角函數索引表的初始化函數的調用不希望由每一個外部使用三角函數的開發者調用,如果在三角函數的包內有一個機制可以告訴三角函數包程序何時啟動,那麼就可以解決初始化的問題。
Go 語言為上述問題提供了一個非常方便的特性:init() 函數。
init() 函數的特性如下:
每個原始碼可以使用 1 個 init() 函數。
init() 函數會在程式執行前(main() 函數執行前)被自動呼叫。
呼叫順序為 main() 中引用的套件,以深度優先順序初始化。
例如,假設有這樣的套件參考關係:main→A→B→C,那麼這些套件的init() 函數呼叫順序為:
C.init→B.init→A.init→main
說明:
同一個套件中的多個init() 函數的呼叫順序不可預期。
init() 函數不能被其他函數呼叫。
理解包导入后的init()函数初始化顺序
Go 语言包会从 main 包开始检查其引用的所有包,每个包也可能包含其他的包。Go 编译器由此构建出一个树状的包引用关系,再根据引用顺序决定编译顺序,依次编译这些包的代码。
在运行时,被最后导入的包会最先初始化并调用 init() 函数。
通过下面的代码理解包的初始化顺序。
代码8-3 包导入初始化顺序入口(…/chapter08/pkginit/main.go)
package main import "chapter08/code8-2/pkg1" func main() { pkg1.ExecPkg1() }
代码说明如下:
第 3 行,导入 pkg1 包。
第 7 行,调用 pkg1 包的 ExecPkg1() 函数。
代码8-4 包导入初始化顺序pkg1(…/chapter08/pkginit/pkg1/pkg1.go)
package pkg1 import ( "chapter08/code8-2/pkg2" "fmt" ) func ExecPkg1() { fmt.Println("ExecPkg1") pkg2.ExecPkg2() } func init() { fmt.Println("pkg1 init") }
代码说明如下:
第 4 行,导入 pkg2 包。
第 8 行,声明 ExecPkg1() 函数。
第 12 行,调用 pkg2 包的 ExecPkg2() 函数。
第 15 行,在 pkg1 包初始化时,打印 pkg1 init。
代码8-5 包导入初始化顺序pkg2(…/chapter08/pkginit/pkg2/pkg2.go)
package pkg2 import "fmt" func ExecPkg2() { fmt.Println("ExecPkg2") } func init() { fmt.Println("pkg2 init") }
代码说明如下:
第 5 行,声明 ExecPkg2() 函数。
第 10 行,在 pkg2 包初始化时,打印 pkg2 init。
执行代码,输出如下:
pkg2 init pkg1 init ExecPkg1 ExecPkg2
以上是Go語言怎麼導入包的詳細內容。更多資訊請關注PHP中文網其他相關文章!