從0開(kāi)始學(xué)Golang之包的使用
開(kāi)發(fā)了一款免費(fèi)的程序員答題小程序,上面的所有問(wèn)題都是來(lái)自于真實(shí)面試題。涵蓋了Redis、MySQL、Golang、PHP等等技術(shù)棧。點(diǎn)擊即可進(jìn)入答題。
包介紹
在使用Golang開(kāi)發(fā)中,我們不可能把所有的項(xiàng)目文件都放在一個(gè)目錄下面。這就需要根據(jù)實(shí)際的項(xiàng)目,將程序文件進(jìn)行歸類,不同的功能放在不同的目錄。這就是包的作用之一,Golang中的包就像PHP中的命名空間類似。
語(yǔ)法
定義包
假設(shè)我們創(chuàng)建了一個(gè)名字叫做pack1的目錄,此時(shí)我們就需要把這個(gè)目錄下面的文件都定義為pack1包名。
pack?pack1
使用關(guān)鍵字
pack+ 包名。包名不能使用Golang自帶的關(guān)鍵字。包名必須放在程序文件的第一行,在定義包之前不能有任何內(nèi)容。
main包作為程序的入口文件,其他的程序目錄不能定義為main包,但是與main包同目錄下面的程序文件可以定義包名為main包。舉個(gè)例子,你定義了一個(gè)程序文件a.go,同時(shí)在該目錄下面定義了程序文件b.go。下面這種寫法是正確的。
//?a.go
pack?main
func?main()?{
??//?todo
}
//?b.go
pack?main
func?show()?{
??//?todo
}
包的使用
當(dāng)前包要使用其他包的元素(變量、函數(shù)、結(jié)構(gòu)體等等),就需要導(dǎo)入到當(dāng)前包。這和PHP中的use語(yǔ)法一樣。Golang中導(dǎo)入包使用關(guān)鍵字import。
//?只到如一個(gè)包
import?"go_demo/src/demo/pack1"
//?導(dǎo)入多個(gè)包
import?(
?"go_demo/src/demo/pack1"
?"go_demo/src/demo/pack2"
)
?上面的兩種寫法都是正確的,主要是看你導(dǎo)入包的數(shù)量,不過(guò)推薦使用第二種,畢竟一個(gè)包基本都會(huì)導(dǎo)入多個(gè)外部包。
?
導(dǎo)包的注意事項(xiàng)
導(dǎo)入的包,根據(jù)包的類型進(jìn)行分組。一般我們把包分為Golang內(nèi)置包和第三方包。推薦使用下面的導(dǎo)包風(fēng)格。中間多一空行,增加代碼的可閱讀性。
import?(
?"os"
?"go_demo/src/demo/pack1"
?"go_demo/src/demo/pack2"
)
盡可能導(dǎo)入需要使用的包,不用的包就不要導(dǎo)入。如果導(dǎo)入的包不使用,在編譯時(shí)會(huì)報(bào)錯(cuò),要解決這個(gè)問(wèn)題,可以使用下面的語(yǔ)法,添加一個(gè)"_"。
import?(
?_?"go_demo/src/demo/pack1"
?"go_demo/src/demo/pack2"
)
包別名。當(dāng)引入第三方包和自身定義的包名,發(fā)生沖突時(shí),可以針對(duì)包做一個(gè)別名。下面的 githubPacke就是一個(gè)包別名。
import?(
?"go_demo/src/demo/pack1"
?githubPacke?"github.com/demo/pack1"
)
調(diào)用包中的屬性時(shí),可以省略包名,但是不推薦這種方式,很容易發(fā)生使用沖突。假設(shè)pack1包中有一個(gè)Show()函數(shù),pack2中有一個(gè)Run()函數(shù)。
import?(
?"go_demo/src/demo/pack1"
?"go_demo/src/demo/pack2"
)
func?Demo()?{
?//?直接省略掉包名。
??Show()
??Run()
}
包屬性。這里的屬性是指,包內(nèi)的變量、結(jié)構(gòu)體、方法、函數(shù)等等。如果在開(kāi)頭字母是小寫,則只能在本包中調(diào)用,不能被外部包調(diào)用。否則會(huì)出現(xiàn) cannot refer to unexported name pack1.demo2類似的錯(cuò)誤信息。下面的Name變量、Demo()1函數(shù)就能被外部包調(diào)用。
var?Name?string
var?age?int
func?Demo1()?{
?pack3.Demo1()
?fmt.Println("pack1->Demo1()")
}
func?demo2()?{
?fmt.Println("pack1->demo2()")
}
調(diào)用外部包時(shí),會(huì)自動(dòng)調(diào)用包中的init()函數(shù)。越底層的包,越先執(zhí)行。下面有main.go文件,packe1.demo1.go文件,pack2.demo1.go和pack3.demo1.go文件。當(dāng)main.go去調(diào)用pack1和pack2的時(shí)候,發(fā)現(xiàn)pack1調(diào)用了pack3,于是最先調(diào)用的包應(yīng)該就是pack3中的init()函數(shù)。 
main.go文件。
import?(
?"go_demo/src/demo/pack1"
?"go_demo/src/demo/pack2"
)
func?main()?{
?pack1.Demo1()
?pack2.Demo1()
}
packe1.demo1.go文件
func?init()?{
?fmt.Println("pack1->init()")
}
func?Demo1()?{
?pack3.Demo1()
?fmt.Println("pack1->Demo1()")
}
packe2.demo1.go文件
func?init()?{
?fmt.Println("pack2->init()")
}
func?Demo1()?{
?fmt.Println("pack2->Demo1()")
}
packe2.demo1.go文件
func?init()?{
?fmt.Println("pack3->init()")
}
func?Demo1()?{
?fmt.Println("pack3->Demo1()")
}
輸出結(jié)果為:
pack3->init()
pack1->init()
pack2->init()
pack3->Demo1()
pack1->Demo1()
pack2->Demo1()
