package 包
- 一个文件夹下只能有一个包, 但可以有多个文件
- 包的作用相当于把一个文件拆分成多个文件, 其实写在一个文件里都是一样的
- 在包中定义常量能直接访问
变量名, 方法名,常量名, 只有大写开头的才能在包外部访问 ,公有私有, 已开头大小写来区分
规范
子包文件和文件夹名字保持一致
小结
- 每个package可以定义多个init函数,甚至在同一个go文件也可以有多个init函数。
- 如果一个包没有import其他包,则多个init按出现顺序初始化
- 同一个包多个文件都有init函数则按文件名顺序初始化
- 一般go fmt的话,会对import进行排序,这样子保证初始化行为的可再现性
如果一个包有import其他包,则按依赖顺序从最里层包开始初始化
doc
- Go语言init函数你必须记住的六个特征
包中 init 函数的执行过程

实践出真理
目录文件结构
/root/workspace/07
.├── go.mod├── main.go├── pkg1│ └── pkg1.go├── pkg2│ └── pkg2.go├── pkg3│ └── pkg3.go├── pkg4│ ├── pkg1│ │ └── pkg1.go│ └── pkg4.go└── pkg5└── pkg5.go6 directories, 8 files
文件列表
main.go
package main// 在 main.go 目录下创建 模块 app 下面的导包命令才正确, 相关知识点查阅, golnag mod// go mod init appimport ("app/pkg1""app/pkg2"_ "app/pkg4"alias "app/pkg4/pkg1". "app/pkg5" // 不推荐"log")func main() {log.Println("-------开始使用包函数-------")pkg1.PkgTest()pkg2.PkgTest()alias.PkgTest()PkgTest()}
pkg1/pkg1.go
package pkg1 //规范,包名与文件所属文件夹名一致import ("app/pkg3""io""log""os")const CV = "const_pkg1"// 函数名首字母大写, 表示 public 属性func PkgTest() {pkg3.PkgTest()log.Println("pkgTest CV=", CV)}func init() {log.SetOutput(io.MultiWriter(os.Stdout))log.SetFlags(log.Lshortfile)log.Println("init CV=", CV)}
pkg2/pkg2.go
package pkg2 //规范,包名与文件所属文件夹名一致import ("io""log""os")const CV = "const_pkg2"// 函数名首字母大写, 表示 public 属性func PkgTest() {log.Println("pkgTest CV=", CV)}func init() {log.SetOutput(io.MultiWriter(os.Stdout))log.SetFlags(log.Lshortfile)log.Println("init CV=", CV)}
pkg3/pkg3.go
package pkg3 //规范,包名与文件所属文件夹名一致import ("io""log""os")const CV = "const_pkg3"// 函数名首字母大写, 表示 public 属性func PkgTest() {log.Println("pkgTest CV=", CV)}func init() {log.SetOutput(io.MultiWriter(os.Stdout))log.SetFlags(log.Lshortfile)log.Println("init CV=", CV)}
pkg4/pkg4.go
// 匿名包示例package pkg4 //规范,包名与文件所属文件夹名一致import ("io""log""os")const CV = "const_pkg4"// 函数名首字母大写, 表示 public 属性func PkgTest() {log.Println("pkgTest CV=", CV)}func init() {log.SetOutput(io.MultiWriter(os.Stdout))log.SetFlags(log.Lshortfile)log.Println("这是一个匿名包测试, 只导入, 不使用=", CV)}
pkg4/pkg1/pkg1.go
// 别名包示例package pkg1 //规范,包名与文件所属文件夹名一致import ("io""log""os")const CV = "pkg4 下的 pkg1"// 函数名首字母大写, 表示 public 属性func PkgTest() {log.Println("pkgTest CV=", CV)}func init() {log.SetOutput(io.MultiWriter(os.Stdout))log.SetFlags(log.Lshortfile)log.Println("这是一个别名包, 包名与 main.go 目录下的 pkg1 一致, 需要用别名的方式引用=", CV)}
运行结果
pkg3.go:20: init CV= const_pkg3pkg1.go:23: init CV= const_pkg1pkg2.go:20: init CV= const_pkg2pkg4.go:22: 这是一个匿名包测试, 只导入, 不使用= const_pkg4pkg1.go:22: 这是一个别名包, 包名与 main.go 目录下的 pkg1 一致, 需要用别名的方式引用= pkg4 下的 pkg1pkg5.go:22: 将包中的函数,常量, 结构体等 引入, 当前包 const_pkg5main.go:16: -------开始使用包函数-------pkg3.go:13: pkgTest CV= const_pkg3pkg1.go:16: pkgTest CV= const_pkg1pkg2.go:13: pkgTest CV= const_pkg2pkg1.go:15: pkgTest CV= pkg4 下的 pkg1pkg5.go:15: pkgTest CV= const_pkg5
