版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fujian9544/article/details/85450036
defer
1.词义
defer推迟 recover恢复 panic恐慌
2.panic
panic 类型interface{}类型
panic恐慌 不会再往下执行了
3.recover
panic 之后不会立刻返回 会传递至defer defer里面有recover的话 会进行捕获panic的内容
4.defer
defer推迟 可以多次推迟 栈的数据结构
5.正常情况
package main
import (
"fmt"
)
func main() {
test()
}
func minicError(key string) error {
return fmt.Errorf("mimic error: %s", key)
}
func test() {
fmt.Println("start test")
err := minicError("1")
defer func() {
fmt.Println("start defer")
if err != nil {
fmt.Println("defer error:", err)
}
}()
fmt.Println("end test")
}
--------------------------------------
start test
end test
start defer
defer error: mimic error:
6.defer与return
return是在defer之后执行的
7.recover与panic
无值时候:Recover方法被调用,但是没有任何的panic发生,recover方法只会返回nil;
有值时候:如果有panic发生,那么panic就停止 并且把panic的赋值传递给recover。
总结:如果有了panic 那么后面的都不执行了 但是会把值传递给recover recover会捕获panic的值 并且程序不会崩溃
7.例子
这个例子说明了recover进行捕获panic的内容
package main
import "fmt"
import "math"
func foo(a int) {
defer fmt.Println("foo退出来了")
defer func() {
if r := recover(); r != nil {
fmt.Printf("捕获到的错误:%s\n", r)
}
}()
if a < 0 {
panic("必须输入大于0的数")
}
fmt.Println("该数的方根为:", math.Sqrt(float64(a)))
}
func main() {
var a int
a = 10
fmt.Printf("a=%d\n", a)
foo(a)
var b int
b = -10
fmt.Printf("b=%d\n", b)
foo(b)
fmt.Println("该goroutine还可以执行")
}
// a=10
// 该数的方根为: 3.1622776601683795
// foo退出来了
// b=-10
// 捕获到的错误:必须输入大于0的数
// foo退出来了
// 该goroutine还可以执行