英文:
golang recover return value syntax
问题
.(error)
部分是类型断言的语法,用于将 recover()
的返回值转换为 error
类型。在这个代码片段中,recover()
函数返回的结果被断言为 error
类型,并赋值给变量 r
。然后通过检查 ok
变量的值,可以确定类型断言是否成功。如果成功,就可以在 fmt.Println()
中打印出错误信息。这样可以更具体地处理恢复操作中的错误情况。
英文:
I'm trying to understand how to recover from panic situation. Normally, something like this will do:
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
I can understand those much. But I've seen code snippet like the following:
if r, ok := recover().(error); ok {
fmt.Println("Recovered in f", r)
}
What's the .(error)
part doing?
答案1
得分: 29
这是一种类型断言,用于检查恢复的错误是否属于某种特定类型。
如果类型断言失败,会导致运行时错误,继续堆栈展开,就好像没有中断一样。
当你为错误定义一个本地的MyError
类型,并且只想从该类型中恢复时,这非常有用。
你可以在“错误处理和Go”中看到一个例子。
> 客户端代码可以通过类型断言来测试是否为net.Error
,然后区分临时网络错误和永久性错误。
> 例如,一个网络爬虫可能会:
> - 在遇到临时错误时休眠并重试
-
否则放弃。
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
time.Sleep(1e9)
continue
}
if err != nil {
log.Fatal(err)
}
如果你有多种类型的错误需要恢复,可以使用类型开关,如“Golang:从defer返回”中所示。
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
// 找出确切的错误并设置err
switch x := r.(type) {
case string:
err = errors.New(x)
case error:
err = x
default:
// 默认错误(根据规范,错误字符串应为小写且不带标点符号)
err = errors.New("unknown panic")
}
// 使rep无效
rep = nil
// 返回修改后的err和rep
}
}()
英文:
It is a type assertion which check if the error recovered is of a certain type.
It that type assertion fails, that causes a run-time error that continues the stack unwinding as though nothing had interrupted it.
This is useful when you define a local MyError
type for error, and you want to recover only from that type.
You can see an example in "Error handling and Go"
> Client code can test for a net.Error with a type assertion and then distinguish transient network errors from permanent ones.
> For instance, a web crawler might:
> - sleep and retry when it encounters a temporary error
-
and give up otherwise.
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
time.Sleep(1e9)
continue
}
if err != nil {
log.Fatal(err)
}
If you have several types of error you want to recover, you can use a type switch is in "Golang: returning from defer"
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
// find out exactly what the error was and set err
switch x := r.(type) {
case string:
err = errors.New(x)
case error:
err = x
default:
// Fallback err (per specs, error strings should be lowercase w/o punctuation
err = errors.New("unknown panic")
}
// invalidate rep
rep = nil
// return the modified err and rep
}
}()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论