08.init函数与import导包
1.init函数

1.1.init函数详解
init()函数会在每个包完成初始化后自动执行,并且执行优先级比main函数高。init函数通常被用来:
- 对变量进行初始化
- 检查/修复程序的状态
- 注册
- 运行一次计算
1.2.包的初始化
为了使用导入的包,首先必须将其初始化。初始化总是以单线程执行,并且按照包的依赖关系顺序执行。这通过Golang的运行时系统控制,如上图所示:
- 初始化导入的包(递归导入)
- 对包块中声明的变量进行计算和分配初始值
- 执行包中的init函数
1.3.示例代码
// 代码结构
├── initFunc.go
├── initFunc_test.go
├── lib1
│ └── lib1.go
└── lib2
└── lib2.go
// lib1.go
package lib1
import "fmt"
// init 函数
func init() {
fmt.Println("lib1==>>init()....")
}
// run
func Run1() {
fmt.Println("lib1====>>>run().....")
}
// lib2.go
package lib2
import "fmt"
// init 函数
func init() {
fmt.Println("lib2==>>init()....")
}
// run
func Run2() {
fmt.Println("lib2====>>>run().....")
}
// initFunc.go
package chapter05
import (
"fmt"
"e.coding.net/ywang/Go/gdev/hour/chapter05/lib1"
"e.coding.net/ywang/Go/gdev/hour/chapter05/lib2"
)
func init() {
fmt.Println("main====>>>> init().....")
}
// main
func Run() {
lib1.Run1()
lib2.Run2()
}
// initFunc_test.go
package chapter05
import "testing"
func TestRun(t *testing.T) {
Run()
}
// 执行结果
lib1==>>init()....
lib2==>>init()....
main====>>>> init().....
=== RUN TestRun
lib1====>>>run().....
lib2====>>>run().....
--- PASS: TestRun (0.00s)
PASS
ok e.coding.net/ywang/Go/gdev/hour/chapter05 0.223s
1.4.说明
- 函数名首字母大写,表示函数可以对外使用,首字母小写表示,只可以包内引用
1.5.每个源文件中可以包含多个init函数
// 修改 lib1.go、lib2.go和 initFunc.go的代码
//lib1.go
package lib1
import "fmt"
// init 函数
func init() {
fmt.Println("lib1==>>init1()....")
}
func init() {
fmt.Println("lib1==>>init2()....")
}
// run
func Run1() {
fmt.Println("lib1====>>>run().....")
}
// lib2.go
package lib2
import "fmt"
// init 函数
func init() {
fmt.Println("lib2==>>init1()....")
}
func init() {
fmt.Println("lib2==>>init2()....")
}
// run
func Run2() {
fmt.Println("lib2====>>>run().....")
}
// initFunc.go
package chapter05
import (
"fmt"
"e.coding.net/ywang/Go/gdev/hour/chapter05/lib1"
"e.coding.net/ywang/Go/gdev/hour/chapter05/lib2"
)
func init() {
fmt.Println("main====>>>> init1().....")
}
func init() {
fmt.Println("main====>>>> init2().....")
}
// main
func Run() {
lib1.Run1()
lib2.Run2()
}
// 执行结果
lib1==>>init1()....
lib1==>>init2()....
lib2==>>init1()....
lib2==>>init2()....
main====>>>> init1().....
main====>>>> init2().....
=== RUN TestRun
lib1====>>>run().....
lib2====>>>run().....
--- PASS: TestRun (0.00s)
PASS
ok e.coding.net/ywang/Go/gdev/hour/chapter05 0.538s
1.6.总结
init函数不需要传入参数,也不会返回任何值init没有被声明,不能被引用![]()
- 每个源文件可以包含多个init函数
2.import导包
2.1.使用_对包进行匿名引用
// initFunc.go
package chapter05
import (
"fmt"
_ "e.coding.net/ywang/Go/gdev/hour/chapter05/lib1"
"e.coding.net/ywang/Go/gdev/hour/chapter05/lib2"
)
func init() {
fmt.Println("main====>>>> init1().....")
}
func init() {
fmt.Println("main====>>>> init2().....")
}
// main
func Run() {
//lib1.Run1()
lib2.Run2()
}
// 执行结果
lib1==>>init1()....
lib1==>>init2()....
lib2==>>init1()....
lib2==>>init2()....
main====>>>> init1().....
main====>>>> init2().....
=== RUN TestRun
lib2====>>>run().....
--- PASS: TestRun (0.00s)
PASS
ok
说明
_ "e.coding.net/ywang/Go/gdev/hour/chapter05/lib1"匿名引用lib1- 执行结果中看到,
lib1下的init函数正常执行 - 无法使用当前包的方式,但是会执行当前包内部的
init方法。
2.2.使用别名导入包
// initFunc.go
package chapter05
import (
"fmt"
_ "e.coding.net/ywang/Go/gdev/hour/chapter05/lib1" // 匿名导入包
mylib2 "e.coding.net/ywang/Go/gdev/hour/chapter05/lib2" // 别名导入包
)
func init() {
fmt.Println("main====>>>> init1().....")
}
func init() {
fmt.Println("main====>>>> init2().....")
}
// main
func Run() {
//lib1.Run1()
// 别名导入包
mylib2.Run2()
// lib2.Run2()
}
// 执行结果
lib1==>>init1()....
lib1==>>init2()....
lib2==>>init1()....
lib2==>>init2()....
main====>>>> init1().....
main====>>>> init2().....
=== RUN TestRun
lib2====>>>run().....
--- PASS: TestRun (0.00s)
PASS
ok
2.3.使用.方式导入包
// initFunc.go
package chapter05
import (
"fmt"
_ "e.coding.net/ywang/Go/gdev/hour/chapter05/lib1" // 匿名导入包
// mylib2 "e.coding.net/ywang/Go/gdev/hour/chapter05/lib2" // 别名导入包
. "e.coding.net/ywang/Go/gdev/hour/chapter05/lib2" // 使用.的方式导入包
)
func init() {
fmt.Println("main====>>>> init1().....")
}
func init() {
fmt.Println("main====>>>> init2().....")
}
// main
func Run() {
//lib1.Run1()
// 别名导入包
// mylib2.Run2()
// lib2.Run2()
// 使用 . 方式导入包,直接调用函数
Run2()
}
// 执行结果
lib1==>>init1()....
lib1==>>init2()....
lib2==>>init1()....
lib2==>>init2()....
main====>>>> init1().....
main====>>>> init2().....
=== RUN TestRun
lib2====>>>run().....
--- PASS: TestRun (0.00s)
PASS
ok
说明
.的方式,不推荐使用,但Go是支持的;原因是多个`- 包内所有方法都可以直接通过API来调用,不需要
包名.API方式使用。
2.4.总结



浙公网安备 33010602011771号