大家好,我是煎魚。
在 Go 這門編程語言中,if err != nil 的錯誤處理方式,是我們一直關注的焦點之一。所有的 Go 社區調查中,都有希望優化和改進錯誤處理的聲音和各種想法。
春節期間刷到了一個由 @Bill Soudan 提出的新提案《proposal: Go 2: support new form of switch statement during variable assignment which jumps to function-wide case blocks[1]》,是針對錯誤處理優化的,思路還是有些新奇的。
圖片
以往印象里沒有人提過這個方式。今天分享給大家,一起圍觀和學習!
該提案希望在變量賦值時能夠支持新的 switch 語句形式。從功能出發,更具體指的是:要支持 switch 跳轉到函數范圍內的任意位置的標簽。
這個特性的目的是:簡化繁瑣又重復的 if err !=nil 的錯誤檢查代碼,也可以用于其他邏輯實現。
具體的對比例子如下。
如果是原本的 Go1 錯誤處理的范式。
代碼如下:
func CopyFile(src, dst string) error { r, err := os.Open(src) if err != nil { return err } defer r.Close() w, err := os.Create(dst) if err != nil { return err } defer w.Close() if _, err := io.Copy(w, r); err != nil { return err } if err := w.Close(); err != nil { return err }}
要寫比較多的判斷和返回錯誤的邏輯,并且這些代碼比正式的調用代碼還要多。所以也常被人戲稱一個 Go 工程里 80% 都是 if err != nil 等錯誤檢查代碼。
基于本文提到的 switch-case 提案進行改造。
新的代碼如下:
func CopyFile(src, dst string) error { r, switch err := os.Open(src) defer r.Close() w, switch err := os.Create(dst) defer w.Close() _, switch dstErr := io.Copy(w, r) switch dstErr = w.Close() return nilcase dstErr != nil: os.Remove(dst) err = dstErr fallthroughcase err != nil: return fmt.Errorf("copy %s %s: %v", src, dst, err)}
注意幾個細節點:
這種 switch-case 的使用方式,從優點來看。確實收攏了統一的錯誤處理邏輯,減少了重復繁瑣的代碼量。
短短的代碼片段,看起來像那么一回事,能一定程度上滿足大家原始的訴求。
缺點的話,個人認為會增加認知和邏輯復雜度。你根本不知道 switch-case,這個 case 他的準確邏輯位置在哪里。
一旦有人套娃,就非常麻煩了。同時 switch-case 延伸出多種不同的使用方式,會產生二義性,這是一個折騰的事情。
今天給大家分享了我所看到的一個 Go 錯誤處理的新提案,其本質上是利用 switch-case 的新語法機制,實現了 err 變量和 case 的關聯。以此簡化錯誤檢查的邏輯。
軟件開發是沒有銀彈的。如何引入更優雅的錯誤處理機制,且不要帶過來過大的程序員心智負擔,還要要確保編譯器性能尚可。Go 核心團隊可能是想要在這三個圈里設計一個最優的選擇。
參考資料
[1]
proposal: Go 2: support new form of switch statement during variable assignment which jumps to function-wide case blocks: https://github.com/golang/go/issues/65019
本文鏈接:http://www.www897cc.com/showinfo-26-75316-0.html用 Switch-case 來解決 Go 錯誤處理的難題?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
下一篇: 想徒手寫個文件系統?來一起呀