defer
- 在函数返回之前, 调用defer函数的操作;
- 函数内可以有多个defered函数, 但是这些defered函数在函数返回时遵守后进先出的原则
- 函数命名的返回值跟defered函数一起使用,,函数的返回值有可能被defer更改。
package mainimport "fmt"func main() { fmt.Println(f()) //输出 3 fmt.Println(g())//输出 5 fmt.Println(h())//输出 1}func f() (rint) { r= 2 defer func() { r++ }() return r}func g() (r int) { t := 5 defer func() { t = t + 5 }() return t}func h() (r int) { defer func(r int) { r = r + 5 }(r) return 1}
- return其实应该包含前后两个步骤:
1.给返回值赋值(若为有名返回值则直接赋值,若为匿名返回值则先声明再赋值);
2.调用RET返回指令并传入返回值,而RET则会检查defer是否存在,若存在就先逆序插播defer语句,最后RET携带返回值退出函数;
上述例子中:f()
是有名返回值,执行return先给result赋值,此时r=2,再执行defer,执行后r=3,最后返回r= 3;g()
有名返回值,执行return先给r赋值,r = t =5,再执行defer,此时修改了t = 10,最后返回的是r=5.
h()
有名返回值,执行return先给r赋值r=1, 但defer里面的r是形参,不会改变到外层的返回值r的值.
panic
类似其它语言的Exception,即异常。
recover
类似其它语言的try catch.
- recover如果想起作用的话, 必须在defered函数中使用.
- 在正常函数执行过程中, 调用recover没有任何作用, 他会返回nil. 如这样:fmt.Println(recover()) // nil
- 如果当前的goroutine panic了, 那么recover将会捕获这个panic的值, 并且让程序正常执行下去, 不会让程序crash.
例子:
package mainimport "fmt"func main() { defer func() { if err := recover(); err!= nil { fmt.Println("Error message:", err) } }() defer func() { fmt.Println("Don't Fuck") }() panic("Fuck you")}
文章来源:智云一二三科技
文章标题:golang之panic/defer/recover
文章地址:https://www.zhihuclub.com/5854.shtml