为什么局部变量的紧急恢复在 Go 中不起作用?
在 Go 中,使用紧急恢复来进行错误处理是常见的做法。然而,在恐慌恢复中使用局部变量作为返回值时,行为上存在细微的差异。
考虑以下代码:
<code class="go">func main() { result, err := foo() fmt.Println("result:", result) if err != nil { fmt.Println("err:", err) } } func foo() (result int, err error) { defer func() { if e := recover(); e != nil { result = -1 err = errors.New(e.(string)) } }() bar() result = 100 err = nil return } func bar() { panic("panic happened") }</code>
当 bar() 中发生恐慌时,recover( ) 延迟闭包中的函数被执行。它将 -1 分配给 result 并创建一个错误对象。此代码的输出是正确的:
result: -1 err: panic happened
但是,如果我们使用局部变量作为返回值:
<code class="go">func main() { result, err := foo() fmt.Println("result:", result) if err != nil { fmt.Println("err:", err) } } func foo() (int, error) { var result int var err error defer func() { if e := recover(); e != nil { result = -1 err = errors.New(e.(string)) } }() bar() result = 100 err = nil return result, err } func bar() { panic("panic happened") }</code>
在这种情况下,输出是不同的:
result: 0
这是因为recover()函数将-1分配给局部变量“result”。但是,由于该函数返回指定的返回值结果(初始化为零),因此局部变量赋值无效。
此行为的原因在于 Go 游览基础知识:
“命名返回值...被视为在函数顶部定义的变量。”
使用命名返回值时,defer 闭包内对它们的更改会反映在返回值中。但是,当使用局部变量时,更改仅反映在局部范围内,而不反映在返回值中。
以上是为什么局部变量的紧急恢复不会改变 Go 中的返回值?的详细内容。更多信息请关注PHP中文网其他相关文章!