我正在试图找出panic()
和recover()
的工作原理..
package log
import (
"fmt"
)
func Recover() {
fmt.Println("Recovering!")
if err := recover(); err != nil {
fmt.Println("Error message recovered!")
}
}
package main
import (
"fmt"
log "www/pkg/log"
)
func main() {
defer func() {
log.Recover()
}()
panic("Fake error!")
}
Recovering!
panic: Fake error!
为什么Error message recovered!
从未打印过?
答案 0 :(得分:2)
应用程序必须直接从延迟函数调用recover来处理恐慌。
specification讨论了调用recover的延迟函数:
假设函数G推迟调用恢复的函数D,并且在执行G的同一goroutine上的函数中发生恐慌。当延迟函数的运行达到D时,D调用recover的返回值将是传递给恐慌调用的值。
它很微妙,但它不允许间接调用恢复。此外,来自恢复的返回值的段落提到了来自延迟函数的直接调用:
如果满足以下任何条件,则恢复的返回值为零:
- 恢复不是由延迟函数直接调用的。
我最近被这个问题抓住了。由于规范非常简洁,有时需要仔细阅读以获取一些要点。
答案 1 :(得分:1)
revocer
仅指执行当前的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
当你调用另一个函数时,它没有恐慌,因此在它的中间调用recover返回nil,你没有发现恐慌。