面试题

这是Go Quiz系列里对于recover的第1篇,次要考查recover函数在什么状况下能够捕捉到panic。

func main() {  fmt.Print("1 ")  defer recover()  fmt.Print("2 ")  var a []int  _ = a[0]  fmt.Print("3 ")}
  • A: 1 2
  • B: 1 2 3
  • C: 1 2 panic
  • D: 1 2 3 panic
  • E: 编译报错

这道题有以下几个考点:

  • defer语句在什么时候执行
  • recover在什么时候能够捕捉到panic

大家能够先暂停,思考下答案。

题目解析

咱们先来回顾下recover, panic的根底知识点:

recover是Go的内置函数,能够捕捉panic异样,然而recover必须联合defer一起应用能力失效。

如果以后goroutine触发了panic,能够在代码的适当地位调用recover函数捕捉异样,让程序持续失常执行,而不是异样终止。

如果程序失常执行过程中,没有panic产生,这时调用recover函数会返回nil,除此之外,没有其它任何成果。

recover在以下几种状况返回nil

  • panic的参数是nil。这种状况recover捕捉后,拿到的返回值也是nil。
  • goroutine没有panic产生。没有panic,那当然recover拿到的也就是nil了。
  • recover不是在被defer的函数外面间接调用执行,这个时候捕捉不到panic,recover函数的返回值是nil。

官网文档的如法如下:

The recover built-in function allows a program to manage behavior of a panicking goroutine. Executing a call to recover inside a deferred function (but not any function called by it) stops the panicking sequence by restoring normal execution and retrieves the error value passed to the call of panic. If recover is called outside the deferred function it will not stop a panicking sequence. In this case, or when the goroutine is not panicking, or if the argument supplied to panic was nil, recover returns nil. Thus the return value from recover reports whether the goroutine is panicking.

recover必须是在被defer的函数外面执行,如果间接在被defer的函数里面执行revcover是不会捕捉到panic的。

对于本题,defer recover()这行代码的recover并不是在被defer的函数里执行,而是间接跟着defer。

所以这道题目的recover捕捉不到panic。因而本题的答案是C,程序输入的后果如下:

1 2 panic: runtime error: index out of range [0] with length 0goroutine 1 [running]:main.main()        /Users/xxx/quiz2.go:11 +0x106exit status 2

思考题

留几道相干的思考题给大家,想晓得答案的能够给自己vx公众号发送音讯recover获取答案和题目解析。

题目1

package mainimport "fmt"func main() {    defer func() { fmt.Println(recover()) }()    defer panic(1)    panic(2)}
  • A: 1
  • B: 2
  • C: 先打印1,而后panic
  • D: 先打印2,而后panic

题目2

func main() {      fmt.Println(recover())    panic(1)}
  • A: 抛panic
  • B: 打印1

题目3

func main() {    defer fmt.Println(recover())    panic(1)}
  • A: 抛panic
  • B: 打印1

题目4

func main() {    defer func() {      func() { fmt.Println(recover()) }()    }()    panic(1)}
  • A: 抛panic
  • B: 打印1

题目5

func main() {    defer func() {      fmt.Println(recover())    }()    panic(1)}
  • A: 抛panic
  • B: 打印1

举荐浏览

  • Go面试题集锦
  • Go Quiz: Google工程师的Go语言面试题
  • Go常见谬误和最佳实际

开源地址

文章和示例代码开源在GitHub: Go语言高级、中级和高级教程。

公众号:coding进阶。关注公众号能够获取最新Go面试题和技术栈。

集体网站:Jincheng's Blog。

知乎:无忌。

福利

我为大家整顿了一份后端开发学习材料礼包,蕴含编程语言入门到进阶常识(Go、C++、Python)、后端开发技术栈、面试题等。

关注公众号「coding进阶」,发送音讯 backend 支付材料礼包,这份材料会不定期更新,退出我感觉有价值的材料。还能够发送音讯「进群」,和同行一起交流学习,答疑解惑。

References

  • https://twitter.com/val_delep...
  • https://chai2010.gitbooks.io/...