go package包的使用
一、标准库
- 引入
在我们之前所写的所以代码中,我们基本上可以看到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小说网