新聞中心
可以在一個 Go語言源文件包聲明語句之后,其它非導(dǎo)入聲明語句之前,包含零到多個導(dǎo)入包聲明語句。每個導(dǎo)入聲明可以單獨(dú)指定一個導(dǎo)入路徑,也可以通過圓括號同時導(dǎo)入多個導(dǎo)入路徑。要引用其他包的標(biāo)識符,可以使用 import 關(guān)鍵字,導(dǎo)入的包名使用雙引號包圍,包名是從 GOPATH 開始計算的路徑,使用/進(jìn)行路徑分隔。

成都創(chuàng)新互聯(lián)是一家專注于網(wǎng)站制作、成都網(wǎng)站設(shè)計與策劃設(shè)計,陽明網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:陽明等地區(qū)。陽明做網(wǎng)站價格咨詢:18982081108
默認(rèn)導(dǎo)入的寫法
導(dǎo)入有兩種基本格式,即單行導(dǎo)入和多行導(dǎo)入,兩種導(dǎo)入方法的導(dǎo)入代碼效果是一致的。
1) 單行導(dǎo)入
單行導(dǎo)入格式如下:
import "包1"
import "包2"
2) 多行導(dǎo)入
當(dāng)多行導(dǎo)入時,包名在 import 中的順序不影響導(dǎo)入效果,格式如下:
import(
"包1"
"包2"
…
)
參考代碼 8-1 的例子來理解 import 的機(jī)制。
本套教程所有源碼下載地址: https://pan.baidu.com/s/1ORFVTOLEYYqDhRzeq0zIiQ 提取密碼:hfyf
代碼 8-1 的目錄層次如下:
.
└── src
└── chapter08
└── importadd
├── main.go
└── mylib
└── add.go
代碼8-1 加函數(shù)(具體文件:…/chapter08/importadd/mylib/add.go)
package mylib
func Add(a, b int) int {
return a + b
}第 3 行中的 Add() 函數(shù)以大寫 A 開頭,表示將 Add() 函數(shù)導(dǎo)出供包外使用。當(dāng)首字母小寫時,為包內(nèi)使用,包外無法引用到。
add.go 在 mylib 文件夾下,習(xí)慣上將文件夾的命名與包名一致,命名為 mylib 包。
代碼8-2 導(dǎo)入包(具體文件:…/chapter08/importadd/main.go)
package main
import (
"chapter08/importadd/mylib"
"fmt"
)
func main() {
fmt.Println(mylib.Add(1, 2))
}代碼說明如下:
- 第 4 行,導(dǎo)入 chapter08/importadd/mylib 包。
- 第 9 行,使用 mylib 作為包名,并引用 Add() 函數(shù)調(diào)用。
在命令行中運(yùn)行下面代碼:
export GOPATH=/home/davy/golangbook/code
go install chapter08/importadd
$GOPATH/bin/importadd
命令說明如下:
- 第 1 行,根據(jù)你的 GOPATH 不同,設(shè)置 GOPATH。
- 第 2 行,使用 go install 指令編譯并安裝 chapter08/code8-1 到 GOPATH 的 bin 目錄下。
- 第 3 行,執(zhí)行 GOPATH 的 bin 目錄下的可執(zhí)行文件 code8-1。
運(yùn)行代碼,輸出結(jié)果如下:
3
導(dǎo)入的包之間可以通過添加空行來分組;通常將來自不同組織的包獨(dú)自分組。包的導(dǎo)入順序無關(guān)緊要,但是在每個分組中一般會根據(jù)字符串順序排列。(gofmt 和 goimports 工具都可以將不同分組導(dǎo)入的包獨(dú)立排序。)
import (
"fmt"
"html/template"
"os"
"golang.org/x/net/html"
"golang.org/x/net/ipv4"
)
導(dǎo)入包后自定義引用的包名
如果我們想同時導(dǎo)入兩個有著名字相同的包,例如 math/rand 包和 crypto/rand 包,那么導(dǎo)入聲明必須至少為一個同名包指定一個新的包名以避免沖突。這叫做導(dǎo)入包的重命名。
import (
"crypto/rand"
mrand "math/rand" // 將名稱替換為mrand避免沖突
)導(dǎo)入包的重命名只影響當(dāng)前的源文件。其它的源文件如果導(dǎo)入了相同的包,可以用導(dǎo)入包原本默認(rèn)的名字或重命名為另一個完全不同的名字。
導(dǎo)入包重命名是一個有用的特性,它不僅僅只是為了解決名字沖突。如果導(dǎo)入的一個包名很笨重,特別是在一些自動生成的代碼中,這時候用一個簡短名稱會更方便。選擇用簡短名稱重命名導(dǎo)入包時候最好統(tǒng)一,以避免包名混亂。選擇另一個包名稱還可以幫助避免和本地普通變量名產(chǎn)生沖突。例如,如果文件中已經(jīng)有了一個名為 path 的變量,那么我們可以將"path"標(biāo)準(zhǔn)包重命名為 pathpkg。
每個導(dǎo)入聲明語句都明確指定了當(dāng)前包和被導(dǎo)入包之間的依賴關(guān)系。如果遇到包循環(huán)導(dǎo)入的情況,Go語言的構(gòu)建工具將報告錯誤。
匿名導(dǎo)入包——只導(dǎo)入包但不使用包內(nèi)類型和數(shù)值
如果只希望導(dǎo)入包,而不使用任何包內(nèi)的結(jié)構(gòu)和類型,也不調(diào)用包內(nèi)的任何函數(shù)時,可以使用匿名導(dǎo)入包,格式如下:
import (
_ "path/to/package"
) 其中,path/to/package 表示要導(dǎo)入的包名,下畫線_表示匿名導(dǎo)入包。
匿名導(dǎo)入的包與其他方式導(dǎo)入包一樣會讓導(dǎo)入包編譯到可執(zhí)行文件中,同時,導(dǎo)入包也會觸發(fā) init() 函數(shù)調(diào)用。
包在程序啟動前的初始化入口:init
在某些需求的設(shè)計上需要在程序啟動時統(tǒng)一調(diào)用程序引用到的所有包的初始化函數(shù),如果需要通過開發(fā)者手動調(diào)用這些初始化函數(shù),那么這個過程可能會發(fā)生錯誤或者遺漏。我們希望在被引用的包內(nèi)部,由包的編寫者獲得代碼啟動的通知,在程序啟動時做一些自己包內(nèi)代碼的初始化工作。
例如,為了提高數(shù)學(xué)庫計算三角函數(shù)的執(zhí)行效率,可以在程序啟動時,將三角函數(shù)的值提前在內(nèi)存中建成索引表,外部程序通過查表的方式迅速獲得三角函數(shù)的值。但是三角函數(shù)索引表的初始化函數(shù)的調(diào)用不希望由每一個外部使用三角函數(shù)的開發(fā)者調(diào)用,如果在三角函數(shù)的包內(nèi)有一個機(jī)制可以告訴三角函數(shù)包程序何時啟動,那么就可以解決初始化的問題。
Go 語言為以上問題提供了一個非常方便的特性:init() 函數(shù)。
init() 函數(shù)的特性如下:
- 每個源碼可以使用 1 個 init() 函數(shù)。
- init() 函數(shù)會在程序執(zhí)行前(main() 函數(shù)執(zhí)行前)被自動調(diào)用。
- 調(diào)用順序為 main() 中引用的包,以深度優(yōu)先順序初始化。
例如,假設(shè)有這樣的包引用關(guān)系:main→A→B→C,那么這些包的 init() 函數(shù)調(diào)用順序為:
C.init→B.init→A.init→main
說明:
- 同一個包中的多個 init() 函數(shù)的調(diào)用順序不可預(yù)期。
- init() 函數(shù)不能被其他函數(shù)調(diào)用。
理解包導(dǎo)入后的init()函數(shù)初始化順序
Go 語言包會從 main 包開始檢查其引用的所有包,每個包也可能包含其他的包。Go 編譯器由此構(gòu)建出一個樹狀的包引用關(guān)系,再根據(jù)引用順序決定編譯順序,依次編譯這些包的代碼。
在運(yùn)行時,被最后導(dǎo)入的包會最先初始化并調(diào)用 init() 函數(shù)。
通過下面的代碼理解包的初始化順序。
代碼8-3 包導(dǎo)入初始化順序入口(…/chapter08/pkginit/main.go)
package main
import "chapter08/code8-2/pkg1"
func main() {
pkg1.ExecPkg1()
}代碼說明如下:
- 第 3 行,導(dǎo)入 pkg1 包。
- 第 7 行,調(diào)用 pkg1 包的 ExecPkg1() 函數(shù)。
代碼8-4 包導(dǎo)入初始化順序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 行,導(dǎo)入 pkg2 包。
- 第 8 行,聲明 ExecPkg1() 函數(shù)。
- 第 12 行,調(diào)用 pkg2 包的 ExecPkg2() 函數(shù)。
- 第 15 行,在 pkg1 包初始化時,打印 pkg1 init。
代碼8-5 包導(dǎo)入初始化順序pkg2(…/chapter08/pkginit/pkg2/pkg2.go)
package pkg2
import "fmt"
func ExecPkg2() {
fmt.Println("ExecPkg2")
}
func init() {
fmt.Println("pkg2 init")
}代碼說明如下:
- 第 5 行,聲明 ExecPkg2() 函數(shù)。
- 第 10 行,在 pkg2 包初始化時,打印 pkg2 init。
執(zhí)行代碼,輸出如下:
pkg2 init
pkg1 init
ExecPkg1
ExecPkg2
本文題目:創(chuàng)新互聯(lián)GO教程:Go語言import導(dǎo)入包——在代碼中使用其他的代碼
鏈接URL:http://m.fisionsoft.com.cn/article/djgjjod.html


咨詢
建站咨詢
