认识Panic和Recover

Panic

这是Golang中的一个内建函数,可以中断原有的控制流程,进入一个令人恐慌的流程中。当函数F调用Panic,函数F的执行将被中断,但是F中的延迟函数会正常执行,然后F返回到调用它的地方。这个恐慌可以直接调用panic产生,也可以由运行时的错误产生。

Recover

Golang的内建函数。可以让进入恐慌的goroutine恢复过来。并且Recover只在延迟函数中有效,在正常情况下goroutine会返回Nil 但是一旦陷入恐慌,Recover就会返回当前的陷入恐慌的panic信息,并恢复程序的正常执行。

DEMO

package main

import (
  "fmt"
)

func ifpanic(){
    //recover

      //unnamed function
      defer func(){
        if r:=recover();r!=nil{
            fmt.Println("recover in ifpanic()",r);
            }
        }()
      //Catch panic
      fmt.Println("Calling panic block");
      panicblock(0);
      fmt.Println("Returning from panicblock normally");
    }

func panicblock(data int){
    //creat a panic manually by recursion
    if data>=3 {
        fmt.Println("panic ing....");
        panic(fmt.Sprintf("%v",data));
        }
     defer fmt.Println("defer block",data)
     fmt.Println("Printing now",data);
     panicblock(data+1)
    }


// func dataOp(data1 float32 ,data2 float32)(float32,float32){
//  
//  return data1+data2,data1*data2
//  }
//只有一个defer 的情景
func main() {
    ifpanic();
    fmt.Printf("Return normally ...");  
}

输出为:

Calling panic block
Printing now 0
Printing now 1
Printing now 2
panic ing....
defer block 2
defer block 1
defer block 0
recover in ifpanic() 3
Return normally ...

有趣的是  如果我们去掉Ifpanic()里面的defer关键字(让其马上执行,不延迟)

即 defer func(){}()  —>  func(){}()

输出马上就会变为:

Calling panic block
Printing now 0
Printing now 1
Printing now 2
panic ing....
defer block 2
defer block 1
defer block 0
panic: 3

goroutine 1 [running]:
main.panicblock(0x3)
    C:/Users/A450V/workspace/godemo/src/main/main.go:26 +0x29d
main.panicblock(0x2)
    C:/Users/A450V/workspace/godemo/src/main/main.go:30 +0x617
main.panicblock(0x1)
    C:/Users/A450V/workspace/godemo/src/main/main.go:30 +0x617
main.panicblock(0x0)
    C:/Users/A450V/workspace/godemo/src/main/main.go:30 +0x617
main.ifpanic()
    C:/Users/A450V/workspace/godemo/src/main/main.go:18 +0x123
main.main()
    C:/Users/A450V/workspace/godemo/src/main/main.go:40 +0x1f

(注:GOPATH 为C:/Users/A450V/workspace/godemo/ )

当异常的JSON数据格式被捕获到,就会优先(first-level)调用PANIC去减轻栈的压力,然后会返回一个error code 并自动调用recover返回程序。。

由此  证实了如定义所说。