使用局部變數進行緊急復原
在 Go 中,使用 defer 函數的緊急復原可以修改周圍函數內的命名回傳值。但是,當局部變數用作傳回值時,此機制無法如預期運作。
考慮以下範例,其中在defer 函數中修改命名回傳值(結果和錯誤):
<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>
這段程式碼從恐慌中恢復並正確修改了命名的回傳值result和err。但是,請考慮以下範例,其中局部變數用作傳回值:
<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>
在這種情況下,defer 函數無法修改 result 和 err 變量,從而導致意外輸出,其中 result 仍為 0。
此行為是由於 defer 語句應用於函數文字而不是周圍函數本身這一事實引起的。因此,局部變數(結果和錯誤)在函數文字中不可存取。相反,命名返回值可以在函數文字中訪問,因為它們本質上是在函數開頭初始化的變數。
以上是Go 中的延遲函數可以在緊急恢復期間修改局部變數嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!