go语言中所有的代码都是在包中的,类似java中的包,c++中的名字空间,包主要用来解决命名冲突问题,在不同的包中存在同名的函数或者struct类型定义是不会冲突的。
1.主包
主包,就是程序的入口函数所在的包,包名叫做main,例子:
// 主包
package main
import "fmt"
// 入口函数
func main() {
fmt.Println("程序入口")
}
go程序执行的时候,首先会找到main包,然后从main包里面找到main函数,执行main函数。
2.定义包
我们可以定义自己的包,通常情况,我们的包名是包所在路径的最后一个目录名,例如:service/order 路径,那么我们包名就是order
语法:
package 包名
例子:
文件:service/order/pay.go
package order
// 定义常量
// 支付宝支付类型
const ORDER_TYPE_ALIPAY = 1
// 微信支付类型
const ORDER_TYPE_WECHAT = 2
// 定义PayOrder结构体类型
type PayOrder struct {
Id int
Price float64
}
关于包的路径,前面搭建开发环境的时候提到GOPATH环境变量指向工作空间,go编译的时候会从$GOPATH/src目录开始搜索包,例如:
我们的项目名:tizi
项目所在目录是:$GOPATH/src/tizi
上面例子的包所在目录为:$GOPATH/src/tizi/service/order/
默认情况,只有这样组织项目和包的目录,才能找到包,否则会报错。
3.导入包
可以通过import导入包,有两种形式导入包:
导入单个包
import "包名"
导入多个包
import (
"包名1"
"包名2"
)
指定包的别名,如果存在两个名字一样的包,可以通过指定别名区分开来
import (
别名 "包名1"
"包名2"
)
例子:
package main
import (
// 导入我们自定义的包order
"tizi/service/order"
"fmt"
)
func main() {
// 使用order包中定义的结构体
o := order.PayOrder{}
o.Id = 100
o.Price = 12.6
fmt.Println(o)
}
4.引用包成员
通过包名和点( . ) 可以引用包里面定义的成员, 成员指的是包里面定义的函数、类型、变量、常量。
例子:
package main
import (
// 导入我们自定义的包order
"tizi/service/order"
"fmt"
)
func main() {
// 引用包中常量
fmt.Println(order.ORDER_TYPE_ALIPAY)
// 引用包中结构体
o := order.PayOrder{}
o.Id = 100
o.Price = 12.6
fmt.Println(o)
}
5.包成员的可见性
在go语言中没有类似public、private针对可见性定义的关键词,在日常开发中,我们肯定希望包中有些成员,外部可以引用,有些成员不允许外部引用。
在go语言中成员可见性是通过首字母大小写区分:
- 首字母大写,代表public,外部可以引用
- 首字母小写,代表private,外部不可以引用
这套根据首字母大小写区分可见性的规则,适用于包中的所有成员,包括结构体、结构体字段、函数、变量、常量。
例子:
package order
// 支付宝支付类型
const ORDER_TYPE_ALIPAY = 1
// 微信支付类型
const ORDER_TYPE_WECHAT = 2
// 定义PayOrder结构体类型
type PayOrder struct {
Id int
price float64 // 首字母小写,包外部无法访问这个字段
}
// 首字母小写,是私有方法,包外部无法引用
func getOrderInfoById(id int) {
}