内容简介:先看下面代码执行结果是:结论:
defer
先看下面代码
func main() { deferCall() fmt.Println("exit main") } func deferCall() { defer fmt.Println("defer 1") defer func() { fmt.Println("defer 2")}() panic("异常") defer func() { fmt.Println("defer 3") if p := recover(); p != nil { fmt.Println("recover", p) } }() time.Sleep(time.Second * 3) fmt.Println("after panic") }
执行结果是:
defer 2 defer 1 panic: 异常 goroutine 1 [running]: main.deferCall() Process finished with exit code 2
结论:
- defer本身也是一条语句,会按函数过程执行
-
defer后面跟的函数,会延迟到所在函数退出时执行
当defer语句被执行时,它后面的函数会被延迟执行,延迟到它所在的函数退出时刻前执行。 -
panic是函数异常退出的点,panic之后的语句不会执行
panic同return语句都为函数的退出点,return是正常退出,panic是异常退出,先执行defer后的函数,再return或panic。panic之后声明的defer函数都不会执行 -
逆序执行
多条defer语句时,它后面的函数执行顺序与声明顺序相反 - recover要在panic之前声明,否则不能捕获到异常
特别说明:
上面的执行打印结果在终端每次输出都一样,但如果在goland IDE中,输出可能会是先panic: 异常,再defer 2 defer 1。这是因为程序是作为goland的子进程执行的,子进程的stdout,stderr分别通过管道重定向到Goland父进程,因此子进程的fmt.println与panic输出可能会出现乱序的情况。
详细参考:Golang中panic和defer的字符串打印顺序
recover
先看如下代码
func deferCall2() { defer fmt.Println("defer 1") defer func() { fmt.Println("defer 2")}() defer func() { fmt.Println("defer 3") if p := recover(); p != nil { fmt.Println("recover", p) } }() defer func() { fmt.Println("defer 4")}() panic("异常") time.Sleep(time.Second * 3) fmt.Println("after panic") }
执行结果:
defer 4 defer 3 recover 异常 defer 2 defer 1 exit main Process finished with exit code 0
结论:
-
panic后,逆序执行defer后的函数,遇到recover内置函数后
recover会使程序从panic中恢复,并返回panic value
defer实现函数trace log
func deferCall3() { // defer表达式会先求值,故下面defer语句会先调用trace函数求得匿名defer函数 defer trace("deferCall3")() time.Sleep(time.Second * 5) } func trace(msg string) func() { start := time.Now() log.Printf("enter %s", msg) return func() { // start的值,这里牵扯到闭包,上下文的概念 log.Printf("exit %s (%s)", msg, time.Since(start)) } }
执行结果:
2019/06/30 21:20:14 enter deferCall3 2019/06/30 21:20:19 exit deferCall3 (5.004000116s) exit main
结论:
- 验证了结论1,defer本身是一条语句,会按顺序执行准备上下文,只是后面跟的函数会延迟执行
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Servlet和JSP学习指南
Budi Kurniawan / 崔毅、俞哲皆、俞黎敏 / 机械工业出版社华章公司 / 2013-4-14 / 59.00元
本书是系统学习Servlet和JSP的必读之作。由全球知名的Java技术专家(《How Tomcat Works》作者)亲自执笔,不仅全面解读Servlet 和JSP 的最新技术,重点阐述Java Web开发的重要编程概念和设计模型,而且包含大量可操作性极强的案例。 本书共18章:第1章介绍Servlet API和几个简单的Servlet;第2章讨论Session追踪,以及保持状态的4种技术......一起来看看 《Servlet和JSP学习指南》 这本书的介绍吧!