init函数
代码
//example.go
package test
import (
"GoExample/util"
"fmt"
)
var A = util.F("example.A")
// 注意:init函数可以重名
func init() {
util.F("example.init1")
}
func init() {
util.F("example.init2")
}
// defer...recover的使用
func DeferRecover() {
//recover会捕获异常,将捕获后的异常信息放到err中
//如果没有异常信息,那么为nil
//匿名函数
defer func() {
err := recover()
if err != nil {
//输出异常信息
fmt.Println(err)
}
}()
n := 0
fmt.Println(3 / n)
}
//util.go
package util
import "fmt"
var i = 0
var F = func(s string) int {
fmt.Printf("本次被%s调用\n", s)
i++
fmt.Printf("匿名工具函数被第%v次调用", i)
return i
}
//main.go
package main
import (
"GoExample/test"
"GoExample/util"
"fmt"
)
var A = util.F("main.A")
// 注意:init函数可以重名
func init() {
util.F("main.init1")
}
func init() {
util.F("main.init2")
}
func main() {
test.DeferRecover()
fmt.Println("test.DeferRecover()之后还在运行")
}
/*
上述代码的执行结果:
本次被example.A调用
匿名工具函数被第1次调用
本次被example.init1调用
匿名工具函数被第2次调用
本次被example.init2调用
匿名工具函数被第3次调用
本次被main.A调用
匿名工具函数被第4次调用
本次被main.init1调用
匿名工具函数被第5次调用
本次被main.init2调用
匿名工具函数被第6次调用
runtime error: integer divide by zero
test.DeferRecover()之后还在运行
*/
init函数的特点
1. init函数在程序中是可选的。
2. init函数不允许有参数和返回值。
3. init函数会自动执行,不允许被调用。
4. 一个程序中可以有多个init函数。
5. 一个包中可能会有多个源程序,因此一个包中也可以有多个init函数。
init函数的执行顺序
这里我们需要分情况讨论:
1. 如果将多个init函数写在了同一个程序中,那么这些init函数就会按照定义的顺序进行调用。
2. 如果同一个包中有多个源程序,而这些源程序中又定义了init函数,那么就会按照名字的字典序来依次调用init函数。
3. 如果存在不同的包,且这些包没有相互的依赖关系(即:一个包import了另一个包),那么就会按照main包的import顺序来依次调用包中的init函数。
4. 如果存在不同的包,且这些包存在相互的依赖关系,那么最后被依赖的包会被最先初始化。例如:main import A A import B B import C C import D。那么,最先执行D包的init,C包的init,B包的init,A包的init,main包的init,main函数。
5. 如果在包中定义了全局变量/全局常量,那么全局变量会先于包的init函数初始化。
参考文献:
https://cloud.tencent.com/developer/article/2138066
标签:调用,函数,util,init,import,main
From: https://www.cnblogs.com/gao79135/p/17739827.html