package 包

  • 一个文件夹下只能有一个包, 但可以有多个文件
  • 包的作用相当于把一个文件拆分成多个文件, 其实写在一个文件里都是一样的
  • 在包中定义常量能直接访问
  • 变量名, 方法名,常量名, 只有大写开头的才能在包外部访问 ,公有私有, 已开头大小写来区分

    规范

  • 子包文件和文件夹名字保持一致

小结

  • 每个package可以定义多个init函数,甚至在同一个go文件也可以有多个init函数。
  • 如果一个包没有import其他包,则多个init按出现顺序初始化
  • 同一个包多个文件都有init函数则按文件名顺序初始化
  • 一般go fmt的话,会对import进行排序,这样子保证初始化行为的可再现性
  • 如果一个包有import其他包,则按依赖顺序从最里层包开始初始化

    doc

  • Package_initialization

  • Go语言init函数你必须记住的六个特征

    包中 init 函数的执行过程

    image.png

实践出真理

目录文件结构

/root/workspace/07

  1. .
  2. ├── go.mod
  3. ├── main.go
  4. ├── pkg1
  5. └── pkg1.go
  6. ├── pkg2
  7. └── pkg2.go
  8. ├── pkg3
  9. └── pkg3.go
  10. ├── pkg4
  11. ├── pkg1
  12. └── pkg1.go
  13. └── pkg4.go
  14. └── pkg5
  15. └── pkg5.go
  16. 6 directories, 8 files

文件列表

main.go

  1. package main
  2. // 在 main.go 目录下创建 模块 app 下面的导包命令才正确, 相关知识点查阅, golnag mod
  3. // go mod init app
  4. import (
  5. "app/pkg1"
  6. "app/pkg2"
  7. _ "app/pkg4"
  8. alias "app/pkg4/pkg1"
  9. . "app/pkg5" // 不推荐
  10. "log"
  11. )
  12. func main() {
  13. log.Println("-------开始使用包函数-------")
  14. pkg1.PkgTest()
  15. pkg2.PkgTest()
  16. alias.PkgTest()
  17. PkgTest()
  18. }

pkg1/pkg1.go

  1. package pkg1 //规范,包名与文件所属文件夹名一致
  2. import (
  3. "app/pkg3"
  4. "io"
  5. "log"
  6. "os"
  7. )
  8. const CV = "const_pkg1"
  9. // 函数名首字母大写, 表示 public 属性
  10. func PkgTest() {
  11. pkg3.PkgTest()
  12. log.Println("pkgTest CV=", CV)
  13. }
  14. func init() {
  15. log.SetOutput(io.MultiWriter(os.Stdout))
  16. log.SetFlags(log.Lshortfile)
  17. log.Println("init CV=", CV)
  18. }

pkg2/pkg2.go

  1. package pkg2 //规范,包名与文件所属文件夹名一致
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. )
  7. const CV = "const_pkg2"
  8. // 函数名首字母大写, 表示 public 属性
  9. func PkgTest() {
  10. log.Println("pkgTest CV=", CV)
  11. }
  12. func init() {
  13. log.SetOutput(io.MultiWriter(os.Stdout))
  14. log.SetFlags(log.Lshortfile)
  15. log.Println("init CV=", CV)
  16. }

pkg3/pkg3.go

  1. package pkg3 //规范,包名与文件所属文件夹名一致
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. )
  7. const CV = "const_pkg3"
  8. // 函数名首字母大写, 表示 public 属性
  9. func PkgTest() {
  10. log.Println("pkgTest CV=", CV)
  11. }
  12. func init() {
  13. log.SetOutput(io.MultiWriter(os.Stdout))
  14. log.SetFlags(log.Lshortfile)
  15. log.Println("init CV=", CV)
  16. }

pkg4/pkg4.go

  1. // 匿名包示例
  2. package pkg4 //规范,包名与文件所属文件夹名一致
  3. import (
  4. "io"
  5. "log"
  6. "os"
  7. )
  8. const CV = "const_pkg4"
  9. // 函数名首字母大写, 表示 public 属性
  10. func PkgTest() {
  11. log.Println("pkgTest CV=", CV)
  12. }
  13. func init() {
  14. log.SetOutput(io.MultiWriter(os.Stdout))
  15. log.SetFlags(log.Lshortfile)
  16. log.Println("这是一个匿名包测试, 只导入, 不使用=", CV)
  17. }

pkg4/pkg1/pkg1.go

  1. // 别名包示例
  2. package pkg1 //规范,包名与文件所属文件夹名一致
  3. import (
  4. "io"
  5. "log"
  6. "os"
  7. )
  8. const CV = "pkg4 下的 pkg1"
  9. // 函数名首字母大写, 表示 public 属性
  10. func PkgTest() {
  11. log.Println("pkgTest CV=", CV)
  12. }
  13. func init() {
  14. log.SetOutput(io.MultiWriter(os.Stdout))
  15. log.SetFlags(log.Lshortfile)
  16. log.Println("这是一个别名包, 包名与 main.go 目录下的 pkg1 一致, 需要用别名的方式引用=", CV)
  17. }

运行结果

  1. pkg3.go:20: init CV= const_pkg3
  2. pkg1.go:23: init CV= const_pkg1
  3. pkg2.go:20: init CV= const_pkg2
  4. pkg4.go:22: 这是一个匿名包测试, 只导入, 不使用= const_pkg4
  5. pkg1.go:22: 这是一个别名包, 包名与 main.go 目录下的 pkg1 一致, 需要用别名的方式引用= pkg4 下的 pkg1
  6. pkg5.go:22: 将包中的函数,常量, 结构体等 引入, 当前包 const_pkg5
  7. main.go:16: -------开始使用包函数-------
  8. pkg3.go:13: pkgTest CV= const_pkg3
  9. pkg1.go:16: pkgTest CV= const_pkg1
  10. pkg2.go:13: pkgTest CV= const_pkg2
  11. pkg1.go:15: pkgTest CV= pkg4 下的 pkg1
  12. pkg5.go:15: pkgTest CV= const_pkg5