每種編程語言都有自己的導(dǎo)包風(fēng)格绞呈,從而來管理自己編寫的程序虏劲。接下來簡單介紹下go中導(dǎo)包語法和部分機制赊抖。
1. Golang包導(dǎo)入
語法
- 與其他程序語言不同吊履,go導(dǎo)入依賴是根據(jù)包名來進行導(dǎo)入的,如打印函數(shù)Println()中使用的導(dǎo)包語句為:
import "fmt"
import代表著導(dǎo)包動作或?qū)О袨?br> "fmt"用字符串表示爷贫,表示要導(dǎo)入的包名
多包導(dǎo)入
- 如果涉及到導(dǎo)入多個包的行為時认然,可以使用:
import "fmt"
import "os"
- 導(dǎo)入多包名時,可能會重復(fù)出現(xiàn)上示代碼塊中同樣的import動作漫萄,go中可以簡化重復(fù)的關(guān)鍵字卷员,并用( )中填充所需要導(dǎo)入的多個包名,如:
import (
"fmt"
"os"
)
導(dǎo)包順序
- 在導(dǎo)入包的過程中腾务,我們可以決定導(dǎo)入包的分組順序毕骡,且可以用空行來凸顯導(dǎo)包模塊的意義
- 在gofmt中,默認將go語言自帶的包置于import模塊上方,而其他包如第三方則github等則置于import模塊的下方未巫,如:
import (
"fmt"
"os"
"golang.org/x/net/ipv4"
)
2. 包循環(huán)依賴問題
錯誤提示
import cycle not allowed
問題原因
-
簡單示意圖:
- 以A/B兩個包舉栗窿撬,如果packageA導(dǎo)入了packageB,而packageB某go文件的 import 中又出現(xiàn)導(dǎo)入packageA的語句時橱赠,就會報錯尤仍。
- 多包導(dǎo)入時,import邏輯出現(xiàn)環(huán)形結(jié)構(gòu)狭姨,則會出現(xiàn)包循環(huán)依賴問題
解決辦法
循環(huán)導(dǎo)包問題是go以包作為單元進行導(dǎo)入的弊端宰啦,業(yè)務(wù)中盡量規(guī)劃好層級關(guān)系,不要出現(xiàn)同層不同包的調(diào)用關(guān)系
(1) 將A/B放于同一個包下饼拍,同包之間不需要import赡模,故不會出現(xiàn)循環(huán)導(dǎo)包問題
弊端:同包情況下,容易導(dǎo)致所有業(yè)務(wù)邏輯代碼出現(xiàn)在同一個包下师抄,包關(guān)系分割不開
(2) 將A/B向上抽出一個關(guān)系層漓柑,將A/B的import和處理邏輯都放在上層
弊端:A/B在同級關(guān)系中又向上抽離出一層,層級關(guān)系過多
3. 包聲明問題
聲明和使用
go導(dǎo)入包時叨吮,默認是用import包的最后包目錄名作為使用名辆布,如下述代碼:
import (
"fmt"
"github.com/go-sql-driver/mysql"
)
導(dǎo)入github.com/go-sql-driver/mysql后,我們可以用mysql.XXX( )來使用調(diào)用mysql包中的變量茶鉴、函數(shù)或方法
別名
在項目搭建過程中锋玲,難免會遇到同包名的沖突情況,而go是嚴格禁止出現(xiàn)相同包名的情況涵叮。因此惭蹂,我們可以向import的同名包聲明下別名,如
import (
"github.com/go-sql-driver/mysql"
rename "github.com/myTest/mysql" // 此包純屬虛構(gòu)
)
在使用過程中割粮,我們便可直接利用rename.XXX( )來調(diào)用myTest/mysql中的函數(shù)
匿名
go中如果導(dǎo)入了包但是沒有使用盾碗,則會編譯報錯:
Unused import
可以使用匿名的方式進行導(dǎo)包,如:
import (
_ "context"
)
場景:用來實現(xiàn)編譯時機制舀瓢,在main函數(shù)中有目的性的加載相應(yīng)的程序包
命名規(guī)則
(1) 言簡意賅廷雅,盡量使用簡短的詞語,且能望文生義京髓,讓包使用者能夠一眼看出包的功能
(2) 盡量避開go自身的包名航缀,如"context", "fmt", "os"等
4. 包使用范圍
??Java語言中,我們常用public朵锣、protected谬盐、default和private等關(guān)鍵字來表示變量和方法的使用范圍甸私,但go中并沒有類似的關(guān)鍵字來表示范圍诚些,而是通過聲明變量和方法名的首字母大小寫來區(qū)分。如:
大寫
fmt.Prinlnt("大寫表示外部包可以使用該方法")
其中fmt的Println( )方法定義為:
func Println(a ...interface{}) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
上述聲明中表示Println( )方法可以暴露給外部,因此我們在導(dǎo)入fmt包使用的時候并不會出現(xiàn)問題诬烹。
小寫
同在fmt包下砸烦,有些方法以小寫字母開頭,這類方法表示不能夠在導(dǎo)入包的情況下使用绞吁,而只能被同package下的其他方法所調(diào)用幢痘。
如:
func tooLarge(x int) bool {
const max int = 1e6
return x > max || x < -max
}
假設(shè)我們從外部調(diào)用,就會看到相應(yīng)的報錯信息:
Unexported function 'tooLarge' usage