关于go:Go-Quiz-从Go面试题看recover注意事项第1篇

6次阅读

共计 2226 个字符,预计需要花费 6 分钟才能阅读完成。

面试题

这是 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 0

goroutine 1 [running]:
main.main()
        /Users/xxx/quiz2.go:11 +0x106
exit status 2

思考题

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

题目 1

package main

import "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/…
正文完
 0