為什麼局部變數的緊急復原在 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中文網其他相關文章!