Go语言与数据库开发:01-09
包和工具
Go語言有超過100個的標(biāo)準(zhǔn)包(譯注:可以用 go list std | wc -l 命令查看標(biāo)準(zhǔn)包的具體數(shù)
目),標(biāo)準(zhǔn)庫為大多數(shù)的程序提供了必要的基礎(chǔ)構(gòu)件。在Go的社區(qū),有很多成熟的包被設(shè)
計、共享、重用和改進(jìn),目前互聯(lián)網(wǎng)上已經(jīng)發(fā)布了非常多的Go語音開源包,它們可以通過
http://godoc.org 檢索。
Go還自帶了工具箱,里面有很多用來簡化工作區(qū)和包管理的小工具。
包簡介
任何包系統(tǒng)設(shè)計的目的都是為了簡化大型程序的設(shè)計和維護(hù)工作,通過將一組相關(guān)的特性放
進(jìn)一個獨立的單元以便于理解和更新,在每個單元更新的同時保持和程序中其它單元的相對
獨立性。這種模塊化的特性允許每個包可以被其它的不同項目共享和重用,在項目范圍內(nèi)、
甚至全球范圍統(tǒng)一的分發(fā)和復(fù)用。
每個包一般都定義了一個不同的名字空間用于它內(nèi)部的每個標(biāo)識符的訪問。每個名字空間關(guān)
聯(lián)到一個特定的包,讓我們給類型、函數(shù)等選擇簡短明了的名字,這樣可以避免在我們使用
它們的時候減少和其它部分名字的沖突。
每個包還通過控制包內(nèi)名字的可見性和是否導(dǎo)出來實現(xiàn)封裝特性。通過限制包成員的可見性
并隱藏包API的具體實現(xiàn),將允許包的維護(hù)者在不影響外部包用戶的前提下調(diào)整包的內(nèi)部實
現(xiàn)。通過限制包內(nèi)變量的可見性,還可以強(qiáng)制用戶通過某些特定函數(shù)來訪問和更新內(nèi)部變
量,這樣可以保證內(nèi)部變量的一致性和并發(fā)時的互斥約束。
當(dāng)我們修改了一個源文件,我們必須重新編譯該源文件對應(yīng)的包和所有依賴該包的其他包。
即使是從頭構(gòu)建,Go語言編譯器的編譯速度也明顯快于其它編譯語言。Go語言的閃電般的編
譯速度主要得益于三個語言特性。第一點,所有導(dǎo)入的包必須在每個文件的開頭顯式聲明,
這樣的話編譯器就沒有必要讀取和分析整個源文件來判斷包的依賴關(guān)系。第二點,禁止包的
環(huán)狀依賴,因為沒有循環(huán)依賴,包的依賴關(guān)系形成一個有向無環(huán)圖,每個包可以被獨立編
譯,而且很可能是被并發(fā)編譯。第三點,編譯后包的目標(biāo)文件不僅僅記錄包本身的導(dǎo)出信
息,目標(biāo)文件同時還記錄了包的依賴關(guān)系。因此,在編譯一個包的時候,編譯器只需要讀取
每個直接導(dǎo)入包的目標(biāo)文件,而不需要遍歷所有依賴的的文件
導(dǎo)入路徑
每個包是由一個全局唯一的字符串所標(biāo)識的導(dǎo)入路徑定位。出現(xiàn)在import語句中的導(dǎo)入路徑也
是字符串。
import (
"fmt"
"math/rand"
"encoding/json"
"golang.org/x/net/html"
"github.com/go-sql-driver/mysql"
)
Go語言的規(guī)范并沒有指明包的導(dǎo)入路徑字符串的具體含義,導(dǎo)
入路徑的具體含義是由構(gòu)建工具來解釋的。
也有第三方擴(kuò)展的工具箱存在。例如,Google
公司內(nèi)部的Go語言碼農(nóng),他們就使用內(nèi)部的多語言構(gòu)建系統(tǒng)。用不同的規(guī)則來處理包名字和定位包,
用不同的規(guī)則來處理單元測試等等,因為這樣可以更緊密適配他們內(nèi)部環(huán)境。
如果你計劃分享或發(fā)布包,那么導(dǎo)入路徑最好是全球唯一的。為了避免沖突,所有非標(biāo)準(zhǔn)庫
包的導(dǎo)入路徑建議以所在組織的互聯(lián)網(wǎng)域名為前綴;而且這樣也有利于包的檢索。例如,上
面的import語句導(dǎo)入了Go團(tuán)隊維護(hù)的HTML解析器和一個流行的第三方維護(hù)的MySQL驅(qū)動。
包聲明
在每個Go語音源文件的開頭都必須有包聲明語句。包聲明語句的主要目的是確定當(dāng)前包被其
它包導(dǎo)入時默認(rèn)的標(biāo)識符。
例如,math/rand包的每個源文件的開頭都包含 package rand 包聲明語句,所以當(dāng)你導(dǎo)入這個
包,你就可以用rand.Int、rand.Float64類似的方式訪問包的成員。
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println(rand.Int())
}
通常來說,默認(rèn)的包名就是包導(dǎo)入路徑名的最后一段,因此即使兩個包的導(dǎo)入路徑不同,它
們依然可能有一個相同的包名。例如,math/rand包和crypto/rand包的包名都是rand。
關(guān)于默認(rèn)包名一般采用導(dǎo)入路徑名的最后一段的約定也有三種例外情況。第一個例外,包對
應(yīng)一個可執(zhí)行程序,也就是main包,這時候main包本身的導(dǎo)入路徑是無關(guān)緊要的。
名字為main的包是給go build構(gòu)建命令一個信息,這個包編譯完之后必須調(diào)用連接器生
成一個可執(zhí)行程序。
第二個例外,包所在的目錄中可能有一些文件名是以test.go為后綴的Go源文件,并且這些源文件聲明的包名也是以
_test為后綴名的。這種目錄可以包含兩種包:一種普通包,加一種則是測試的外部擴(kuò)展包。
所有以_test為后綴包名的測試外部擴(kuò)展包都由go test命令獨立編譯,普通包和測試的外部擴(kuò)
展包是相互獨立的。
第三個例外,一些依賴版本號的管理工具會在導(dǎo)入路徑后追加版本號信息
導(dǎo)入聲明
可以在一個Go語言源文件包聲明語句之后,其它非導(dǎo)入聲明語句之前,包含零到多個導(dǎo)入包
聲明語句。每個導(dǎo)入聲明可以單獨指定一個導(dǎo)入路徑,也可以通過圓括號同時導(dǎo)入多個導(dǎo)入
路徑。
下面兩個導(dǎo)入形式是等價的,但是第二種形式更為常見。
import "fmt"
import "os"
import (
"fmt"
"os"
)
導(dǎo)入的包之間可以通過添加空行來分組;通常將來自不同組織的包獨自分組。包的導(dǎo)入順序
無關(guān)緊要,但是在每個分組中一般會根據(jù)字符串順序排列。
import (
"fmt"
"html/template"
"os"
"golang.org/x/net/html"
"golang.org/x/net/ipv4"
)
如果我們想同時導(dǎo)入兩個有著名字相同的包,例如math/rand包和crypto/rand包,那么導(dǎo)入聲
明必須至少為一個同名包指定一個新的包名以避免沖突。這叫做導(dǎo)入包的重命名。
import (
"crypto/rand"
mrand "math/rand" // alternative name mrand avoids conflict
)
導(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)建工具將報告錯誤。
總結(jié)
以上是生活随笔為你收集整理的Go语言与数据库开发:01-09的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bootstrap .navbar-he
- 下一篇: Mysql Hunter