上次一起写了 3 个案例,咱们这一次持续,这一次的会比上一次的略微不太一样
案例 1
还有一个也十分罕用的案例,应用 defer 来捕捉异样,也就是当程序解体的时候,defer 语句能够帮咱们兜底,能够捕捉异样后依照咱们冀望的逻辑进行执行,让程序回到正确的轨道下面
- 个别使程序解体很简略,C/C++ 的时候,咱们能够造异样,例如除 0,或者是数组越界等等就会导致程序解体
- GO 外面造异样也能够依照下面这种形式,然而咱们也能够应用 panic 函数来实现程序解体
- 写一个简略的例子,把本人的程序搞崩
func testDefer() {defer func() {fmt.Println("panic 前")
}()
panic("i panic")
defer func() {fmt.Println("panic 后")
}()}
func main() {testDefer()
fmt.Println("program over")
}
其实咱们看 goland 工具就能够看到,上面这一句话是不会被执行的
`defer func() {
fmt.Println("panic 后")
}()`
理论运行程序后,后果如下:
咱们能够看到实际效果,程序是解体了,因为 fmt.Println("program over")
没有打印进去,且看图片,是有具体的 panic 信息的
从上述能够看明确,panic 之后的程序是不会执行的,panic 之前的 defer 语句会执行,因为他先入栈了
那么咱们来捕捉一下异样
还是下面的代码,咱们来捕捉一下异样,就是加一句话就能够了
func testDefer() {defer func() {fmt.Println("panic 前")
if err := recover(); err != nil {fmt.Println("xdm , 我捕捉到异样了,程序不必解体了")
}
}()
panic("i panic") // 触发 defer 出栈
defer func() {fmt.Println("panic 后")
}()}
func main() {testDefer()
fmt.Println("program over")
}
看上述代码,panic 之后的程序依然是不会执行的,然而咱们退出了 recover() 语句,他会帮忙咱们捕捉异样,解决异样
执行上述代码后,成果如下:
> go run main.go
panic 前
xdm , 我捕捉到异样了,程序不必解体了
program over
依据打印咱们能够看出,论断和下面一个例子论断统一,并且退出异样捕捉之后,程序的解体堆栈信息是不会打印进去了,并且程序是失常退出了,咱们能够看到失常打印了 program over
案例 2
咱们再来字后一个 案例 玩一下
下面都是呈现 1 个 panic 的状况,那么,如果是呈现多个 panic 是怎么玩的呢,defer 他还能捕捉到 panic 信息吗?若呈现 2 个 panic,defer 也能捕捉 2 个吗?
func main() {defer func() {if err := recover(); err != nil {fmt.Println("xdm, 我捕捉到异样了")
}
}()
defer func() {panic("defer func panic")
}()
panic("i panic")
panic("last panic")
fmt.Println("baibai")
}
看到上述代码,一时间晓得怎么走,然而咱们看 goland 就晓得 panic 前面的语句必定不会执行
尝试剖析一下,后面有说,defer 是依照栈的程序来的
- 第 1 个 derfer 先入栈
- 第 2 个 defer 后入栈
- 执行 panic 程序解体 应该会报错
i panic
- 然而程序退出的时候,会出栈,会先执行 第 2 个 defer,这个 defer 也是一个 panic,则会笼罩方才的 panic 信息,应该会报错
defer func panic
- 执行出栈,执行到第 1 个 defer,异样被捕捉了,程序失常退出,因而执行程序会有如下后果
xdm, 我捕捉到异样了
好了,明天就到这里,感兴趣的敌人也能够玩起来
欢送点赞,关注,珍藏
敌人们,你的反对和激励,是我保持分享,提高质量的能源
好了,本次就到这里
技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。
我是 阿兵云原生,欢送点赞关注珍藏,下次见~