一、標准庫
- 引入
在我們之前所寫的所以代碼中,我們基本上可以看到fmt這個導入的包,但是我們卻不知道如何去寫這種包。
如果我們可以自己去寫,那么我們就可以將一個功能的集合統一的放入包中,便於以后使用,那么我們如何去寫這種包呢?
- go的標准庫
在將自定義包之前我們可以先簡單的看一下,fmt 我們是從哪里導過來的?我們可以自己去自己的GOROOT/src 下去查看,你們可以看到大致如下的包
src/
|- archive
|- bufio
|- builtin
|- bytes
.....
這一些的包,這些包我們稱之為 go的標准庫
想這樣的包go 一共給我們提供來150個以上
- 關於包的講解可以去 go中文社區查看
二、自定義包
- 包的聲明
package pakName // 此行必須寫在第一行,且一個文件夾下的所有文件必須使用同一個包名
- 包的導入
import ( // 導入包名必須寫在package 包的聲明下面
pak
....
)
-
實例
day14/calculator/calc.go
package calc
import "errors"
func Calc(num1,num2 int,operator string) (int,error){
switch operator{
case "+":
return sum(num1,num2),nil
case "-":
return red(num1,num2),nil
case "*":
return ride(num1,num2),nil
case "/":
return exc(num1,num2),nil
default:
return 0,errors.New("不合法的運算符")
}
}
- 解釋
pack calc
聲明 day14/calculator/calc.go 屬於calc 包
一個go文件有且僅輸入一個包,一個包可以有多個go文件
import errors
導入標准庫 errors 包
func Calc(){}
// 聲明函數Calc ,
// 在go語言中 變量、類型、函數、方法 首字母大寫表示 外部可以訪問
三、關於包的使用
3.1 自定義calc 包
- 目錄
day14/
|- calc.go
|- exc.go
|- red.go
|- ride.go
|- sum.go
- calc.go
package calc
import "errors"
func Calc(num1,num2 int,operator string) (int,error){
switch operator{
case "+":
return sum(num1,num2),nil
case "-":
return red(num1,num2),nil
case "*":
return ride(num1,num2),nil
case "/":
return exc(num1,num2),nil
default:
return 0,errors.New("不合法的運算符")
}
}
- exc.go
package calc
func exc(num1,num2 int)int{
return num1 / num2
}
- red.go
package calc
func red(num1,num2 int)int{
return num1 - num2
}
- ride.go
package calc
func ride(num1,num2 int)int{
return num1 * num2
}
- sum.go
package calc
func sum(num1,num2 int)int{
return num2 + num1
}
- 注意事項
1、
day14/calculator文件夾下每個文件的聲明 都是
package calc
表明 calculator下的所有文件(不包含文件夾)都屬於calc包
2、
calculator文件夾的文件已經是calc包下的文件了,如果聲明成其他包名,則編譯會無法通過
3、
一個go文件有且僅屬於一個包,一個包可以有多個go文件組成
4、
包的命名要簡潔、清晰且全小寫
3.2 使用自定義包
- 調用calc包
day14/example1/main.go
package main
import (
"day17/day14/calculator"
"fmt"
)
func main(){
var (
num1 int = 12
num2 int = 4
)
result,err := calc.Calc(num1,num2,"-")
if err != nil{
fmt.Println(err)
return
}
fmt.Printf("運算結果為:%v\n",result)
}
- 注意事項
外部調用calc包,只能使用Calc函數,如果使用calc包中的sum,exc,ride..這些方法,則會編譯報錯
因為calc包中 只有Calc函數允許外部訪問,因為Calc 方法大寫開頭,所以允許外部訪問
再次強調
包中的變量、類型、函數、方法,只有大寫字母開頭才能夠被外部調用
四、結構體之包的使用
- 結構體工廠
day14/baozi/factory.go
package baozi
import "fmt"
// 創建工廠結構體
type baozi struct{
Kind string // 包子的種類
}
func (this *baozi) Product(){
switch this.Kind {
case "rou":
fmt.Println("生產了一個肉包")
case "cai":
fmt.Println("生產了一個菜包")
default:
fmt.Println("生產了一個未知包")
}
}
func NewBaozi(kind string)*baozi{
return &baozi{kind}
}
- 包子工廠類的講解
1、
type baozi struct{
Kind string // 包子的種類
}
在包子 包中我們創建了一個結構體,但是該結構體外部無法訪問使用,
因為小寫字母開頭,只能內部使用
2、
func NewBaozi(kind string)*baozi{
return &baozi{kind}
}
在包子 包中提供了一個函數NewBaozi,只能通過調用NewBaozi創建baozi結構體
3、
為什么我們要通過NewBaozi函數創建結構體,而不直接使用baozi.baozi的方式創建呢?
通過函數創建結構體口可以忽略創建的細節。
- 如何使用包子包中的結構體
day14/example2/main
package main
import (
"day17/day14/baozi"
"fmt"
)
func main(){
//baozi := baozi.baozi{"rou"} // 無法使用,因為baozi結構體 小寫開頭
baozi := baozi.NewBaozi("rou")
fmt.Println("包子的種類",baozi.Kind)
baozi.Product()
}
包子的種類 rou
生產了一個肉包
五、包的初始化init
day17/da14/test/init.go
package test
import "fmt"
func init(){
fmt.Println("test -- init")
}
func Test(){
fmt.Println("this is test.test")
}
day17/da14/test1/init.go
package test1
import "fmt"
func init(){
fmt.Println("test1 -- init")
}
day17/da14/emample3/main.go
package main
import (
"fmt"
"day17/day14/test"
_ "day17/day14/test1" // _ 表示只執行init 函數,因為我們並不需要所有的函數
)
func init(){
fmt.Println("main -- init ")
}
func main(){
fmt.Println("main--main")
test.Test()
}
執行結果:
test -- init
test1 -- init
main -- init
main--main
this is test.test
結論:
1、init 函數會在main 函數之前執行
2、go 程序會更具導入包的順序依次執行每一個包的init 函數
六、程序加載過程
如果喜歡看小說,請到183小說網