defer是go提供的一种延迟执行机制。
当执行defer时,会将对应的函数压入栈中,在函数返回或者panic异常结束时,go会从栈中取出延迟函数执行。
func main(){ defer fmt.Println("1") defer fmt.Println("2") defer fmt.Println("3") fmt.Println("hello") }
打印结果为
hello 3 2 1
i := 1 defer fmt.Printf("first is %d\n", i) //1 i = 2 fmt.Printf("current is %d\n", i)//2
当 defer 以闭包的方式引用外部变量时,则会在延迟函数真正执行的时候,根据整个上下文确定当前的值
func main() { fmt.Println(test()) } func test() (i int) { defer func() { i++ }() return 1 }
打印结果是2
panic是一个严重错误机制,它会导致程序终止,并依次逆序执行 panic 所在函数可能存在的 defer 函数列表,然后返回该函数的调用方。
recover 内置函数可用于捕获 panic,重新恢复程序正常执行流程,但是 recover 函数只有在 defer 内部使用才有效
func main() { err := panicAndReturnErr() if err != nil{ fmt.Printf("err is %+v\n", err) } fmt.Println("returned normally from panicAndReturnErr") } func panicAndReturnErr() (err error){ defer func() {//如果defer内有recover,则从 panic 中恢复,不会终止程序 if e := recover(); e != nil {//error occur! // 打印栈信息 buf := make([]byte, 1024) buf = buf[:runtime.Stack(buf, false)] err = fmt.Errorf("[PANIC]%v\n%s\n", e, buf) } }() fmt.Println("panic begin") panic("error occur!")//开始执行defer函数 fmt.Println("panic over") return nil }
下一个:k8s入门之pod