defer panic recover

版权声明:本文为博主原创文章,未经博主允许不得转载。 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还可以执行

猜你喜欢

转载自blog.csdn.net/fujian9544/article/details/85450036