新聞中心
Go語言是使用包來組織源代碼的,包(package)是多個(gè) Go 源碼的集合,是一種高級的代碼復(fù)用方案。Go語言中為我們提供了很多內(nèi)置包,如 fmt、os、io 等。

成都創(chuàng)新互聯(lián)公司不只是一家網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司;我們對營銷、技術(shù)、服務(wù)都有自己獨(dú)特見解,公司采取“創(chuàng)意+綜合+營銷”一體化的方式為您提供更專業(yè)的服務(wù)!我們經(jīng)歷的每一步也許不一定是最完美的,但每一步都有值得深思的意義。我們珍視每一份信任,關(guān)注我們的網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作質(zhì)量和服務(wù)品質(zhì),在得到用戶滿意的同時(shí),也能得到同行業(yè)的專業(yè)認(rèn)可,能夠?yàn)樾袠I(yè)創(chuàng)新發(fā)展助力。未來將繼續(xù)專注于技術(shù)創(chuàng)新,服務(wù)升級,滿足企業(yè)一站式網(wǎng)絡(luò)營銷推廣需求,讓再小的品牌網(wǎng)站建設(shè)也能產(chǎn)生價(jià)值!
任何源代碼文件必須屬于某個(gè)包,同時(shí)源碼文件的第一行有效代碼必須是package pacakgeName 語句,通過該語句聲明自己所在的包。
包的基本概念
Go語言的包借助了目錄樹的組織形式,一般包的名稱就是其源文件所在目錄的名稱,雖然Go語言沒有強(qiáng)制要求包名必須和其所在的目錄名同名,但還是建議包名和所在目錄同名,這樣結(jié)構(gòu)更清晰。
包可以定義在很深的目錄中,包名的定義是不包括目錄路徑的,但是包在引用時(shí)一般使用全路徑引用。比如在GOPATH/src/a/b/ 下定義一個(gè)包 c。在包 c 的源碼中只需聲明為package c,而不是聲明為package a/b/c,但是在導(dǎo)入 c 包時(shí),需要帶上路徑,例如import "a/b/c"。
包的習(xí)慣用法:
- 包名一般是小寫的,使用一個(gè)簡短且有意義的名稱。
- 包名一般要和所在的目錄同名,也可以不同,包名中不能包含
-等特殊符號。 - 包一般使用域名作為目錄名稱,這樣能保證包名的唯一性,比如 GitHub 項(xiàng)目的包一般會放到
GOPATH/src/github.com/userName/projectName目錄下。 - 包名為 main 的包為應(yīng)用程序的入口包,編譯不包含 main 包的源碼文件時(shí)不會得到可執(zhí)行文件。
- 一個(gè)文件夾下的所有源碼文件只能屬于同一個(gè)包,同樣屬于同一個(gè)包的源碼文件不能放在多個(gè)文件夾下。
包的導(dǎo)入
要在代碼中引用其他包的內(nèi)容,需要使用 import 關(guān)鍵字導(dǎo)入使用的包。具體語法如下:
import "包的路徑"
注意事項(xiàng):
- import 導(dǎo)入語句通常放在源碼文件開頭包聲明語句的下面;
- 導(dǎo)入的包名需要使用雙引號包裹起來;
- 包名是從
GOPATH/src/后開始計(jì)算的,使用/進(jìn)行路徑分隔。
包的導(dǎo)入有兩種寫法,分別是單行導(dǎo)入和多行導(dǎo)入。
單行導(dǎo)入
單行導(dǎo)入的格式如下:
import "包 1 的路徑"
import "包 2 的路徑"
多行導(dǎo)入
多行導(dǎo)入的格式如下:
import (
"包 1 的路徑"
"包 2 的路徑"
)
包的導(dǎo)入路徑
包的引用路徑有兩種寫法,分別是全路徑導(dǎo)入和相對路徑導(dǎo)入。
全路徑導(dǎo)入
包的絕對路徑就是GOROOT/src/或GOPATH/src/后面包的存放路徑,如下所示:
import "lab/test"
import "database/sql/driver"
import "database/sql"
上面代碼的含義如下:
- test 包是自定義的包,其源碼位于
GOPATH/src/lab/test目錄下; - driver 包的源碼位于
GOROOT/src/database/sql/driver目錄下; - sql 包的源碼位于
GOROOT/src/database/sql目錄下。
相對路徑導(dǎo)入
相對路徑只能用于導(dǎo)入GOPATH 下的包,標(biāo)準(zhǔn)包的導(dǎo)入只能使用全路徑導(dǎo)入。
例如包 a 的所在路徑是GOPATH/src/lab/a,包 b 的所在路徑為GOPATH/src/lab/b,如果在包 b 中導(dǎo)入包 a ,則可以使用相對路徑導(dǎo)入方式。示例如下:
// 相對路徑導(dǎo)入
import "../a"
當(dāng)然了,也可以使用上面的全路徑導(dǎo)入,如下所示:
// 全路徑導(dǎo)入
import "lab/a"
包的引用格式
包的引用有四種格式,下面以 fmt 包為例來分別演示一下這四種格式。
1) 標(biāo)準(zhǔn)引用格式
import "fmt"
此時(shí)可以用fmt.作為前綴來使用 fmt 包中的方法,這是常用的一種方式。
示例代碼如下:
package main
import "fmt"
func main() {
fmt.Println("C語言中文網(wǎng)")
}2) 自定義別名引用格式
在導(dǎo)入包的時(shí)候,我們還可以為導(dǎo)入的包設(shè)置別名,如下所示:
import F "fmt"
其中 F 就是 fmt 包的別名,使用時(shí)我們可以使用F.來代替標(biāo)準(zhǔn)引用格式的fmt.來作為前綴使用 fmt 包中的方法。
示例代碼如下:
package main
import F "fmt"
func main() {
F.Println("C語言中文網(wǎng)")
}3) 省略引用格式
import . "fmt"
這種格式相當(dāng)于把 fmt 包直接合并到當(dāng)前程序中,在使用 fmt 包內(nèi)的方法是可以不用加前綴fmt.,直接引用。
示例代碼如下:
package main
import . "fmt"
func main() {
//不需要加前綴 fmt.
Println("C語言中文網(wǎng)")
}4) 匿名引用格式
在引用某個(gè)包時(shí),如果只是希望執(zhí)行包初始化的 init 函數(shù),而不使用包內(nèi)部的數(shù)據(jù)時(shí),可以使用匿名引用格式,如下所示:
import _ "fmt"
匿名導(dǎo)入的包與其他方式導(dǎo)入的包一樣都會被編譯到可執(zhí)行文件中。
使用標(biāo)準(zhǔn)格式引用包,但是代碼中卻沒有使用包,編譯器會報(bào)錯(cuò)。如果包中有 init 初始化函數(shù),則通過import _ "包的路徑" 這種方式引用包,僅執(zhí)行包的初始化函數(shù),即使包沒有 init 初始化函數(shù),也不會引發(fā)編譯器報(bào)錯(cuò)。
示例代碼如下:
package main
import (
_ "database/sql"
"fmt"
)
func main() {
fmt.Println("C語言中文網(wǎng)")
}注意:
- 一個(gè)包可以有多個(gè) init 函數(shù),包加載時(shí)會執(zhí)行全部的 init 函數(shù),但并不能保證執(zhí)行順序,所以不建議在一個(gè)包中放入多個(gè) init 函數(shù),將需要初始化的邏輯放到一個(gè) init 函數(shù)里面。
- 包不能出現(xiàn)環(huán)形引用的情況,比如包 a 引用了包 b,包 b 引用了包 c,如果包 c 又引用了包 a,則編譯不能通過。
- 包的重復(fù)引用是允許的,比如包 a 引用了包 b 和包 c,包 b 和包 c 都引用了包 d。這種場景相當(dāng)于重復(fù)引用了 d,這種情況是允許的,并且 Go 編譯器保證包 d 的 init 函數(shù)只會執(zhí)行一次。
包加載
通過前面一系列的學(xué)習(xí)相信大家已經(jīng)大體了解了 Go 程序的啟動(dòng)和加載過程,在執(zhí)行 main 包的 mian 函數(shù)之前, Go 引導(dǎo)程序會先對整個(gè)程序的包進(jìn)行初始化。整個(gè)執(zhí)行的流程如下圖所示。
圖:Go 包的初始化
Go語言包的初始化有如下特點(diǎn):
- 包初始化程序從 main 函數(shù)引用的包開始,逐級查找包的引用,直到找到?jīng)]有引用其他包的包,最終生成一個(gè)包引用的有向無環(huán)圖。
- Go 編譯器會將有向無環(huán)圖轉(zhuǎn)換為一棵樹,然后從樹的葉子節(jié)點(diǎn)開始逐層向上對包進(jìn)行初始化。
- 單個(gè)包的初始化過程如上圖所示,先初始化常量,然后是全局變量,最后執(zhí)行包的 init 函數(shù)。
文章名稱:創(chuàng)新互聯(lián)GO教程:Go語言包的基本概念
文章地址:http://m.5511xx.com/article/cccdogo.html


咨詢
建站咨詢
