在 Go 中使用命名返回變數捕獲 panic

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。這將是一個簡短的文章,靈感來源於 Sean Kelly 十一月份的推特。> 我發現了一個在 golang 中使用指定的傳回值的原因並且現在我感到潸然淚下。 >                     — Sean Kelly (@StabbyCutyou) 2017年11月15日其目標是為了記錄並說明一種有必要使用到命名返回變數的情況,所以說讓我們進入正題。想象你正在編寫一些用了可能 panic 的函數的代碼,並且無論什麼原因(第三方庫,向後相容,等等)你都不能改變那些函數。```gofunc pressButton() { fmt.Println("I'm Mr. Meeseeks, look at me!!")// other stuff then happens, but if Jerry asks to // remove 2 strokes from his golf game...panic("It's gettin' weird!")}```你仍然需要用到那個函數,不過如果它發生異常,而你想要捕獲到這個 panic 並將它作為一個 error 返回,那麼你應該寫一些類似這樣的代碼:```gofunc doStuff() error { var err error// If there is a panic we need to recover in a deferred funcdefer func() {if r := recover(); r != nil {err = errors.New("the meeseeks went crazy!")}}()pressButton()return err}```在 Go Playground 上執行它 - https://play.golang.org/p/wzkjKGqFPL之後你 go run 了你的代碼然而...這是什嗎?你的 error 是 `nil` 值,甚至是在代碼發生異常的時候。這並不是我們想要的!## 為什麼會發生這種情況?雖然最初看起來我們的代碼返回的是我們在函數開始時建立的 `var err error`,但事實上,我們的程式永遠不會到達這一行代碼。這意味著它永遠不會返回特定的 err 變數,而且在我們的 defer 函數內部改變它,最終會變得毫無意義。在調用 `pressButton` 之後添加一個 `Println`,但在返回之前,確實有助於說明這一點:```gopressButton() // Nothing below here gets executed!fmt.Println("we got here!") return err ```在 Go Playground 上執行它 - https://play.golang.org/p/Vk0DYs20eB## 我們該如何修複它為了修複這個問題,我們可以簡單地使用命名返回變數。```gofunc doStuff() (err error) { // If there is a panic we need to recover in a deferred funcdefer func() {if r := recover(); r != nil {err = errors.New("the meeseeks went crazy!")}}()pressButton()return err}```在 Go Playground 上執行它 - https://play.golang.org/p/bqGOroPjQJ最終的代碼看起來非常的相似,不過通過命名我們的返回變數,當我們聲明這個函數時,我們的程式將會立刻返回這個 `err` 變數,即使我們從未觸碰到 `doStuff` 函數的末尾的返回語句。由於這個細微的差別,現在我們可以更改被我們 defer 的函數中的 `err` 變數,並且成功地捕獲到這個 panic。

via: https://www.calhoun.io/using-named-return-variables-to-capture-panics-in-go/

作者:Jon Calhoun 譯者:Maple24 校對:polaris1119

本文由 GCTT 原創編譯,Go語言中文網 榮譽推出

本文由 GCTT 原創翻譯,Go語言中文網 首發。也想加入譯者行列,為開源做一些自己的貢獻嗎?歡迎加入 GCTT!
翻譯工作和譯文發表僅用於學習和交流目的,翻譯工作遵照 CC-BY-NC-SA 協議規定,如果我們的工作有侵犯到您的權益,請及時聯絡我們。
歡迎遵照 CC-BY-NC-SA 協議規定 轉載,敬請在本文中標註並保留原文/譯文連結和作者/譯者等資訊。
文章僅代表作者的知識和看法,如有不同觀點,請樓下排隊吐槽

460 次點擊  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.