一、标准库
- 引入
在我们之前所写的所以代码中,我们基本上可以看到fmt这个导入的包,但是我们却不知道如何去写这种包。 如果我们可以自己去写,那么我们就可以将一个功能的集合统一的放入包中,便于以后使用,那么我们如何去写这种包呢?
- go的标准库
在将自定义包之前我们可以先简单的看一下,fmt 我们是从哪里导过来的?我们可以自己去自己的GOROOT/src 下去查看,你们可以看到大致如下的包 src/ |- archive |- bufio |- builtin |- bytes ..... 这一些的包,这些包我们称之为 go的标准库 想这样的包go 一共给我们提供来150个以上
- 关于包的讲解可以去 查看
二、自定义包
- 包的声明
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 baoziimport "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 mainimport ( "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 testimport "fmt"func init(){ fmt.Println("test -- init")}func Test(){ fmt.Println("this is test.test")}
day17/da14/test1/init.go
package test1import "fmt"func init(){ fmt.Println("test1 -- init")}
day17/da14/emample3/main.go
package mainimport ( "fmt" "day17/day14/test" _ "day17/day14/test1" // _ 表示只执行init 函数,因为我们并不需要所有的函数)func init(){ fmt.Println("main -- init ")}func main(){ fmt.Println("main--main") test.Test()}
执行结果:test -- inittest1 -- initmain -- init main--mainthis is test.test
结论:1、init 函数会在main 函数之前执行2、go 程序会更具导入包的顺序依次执行每一个包的init 函数
六、程序加载过程
如果喜欢看小说,请到