切換語言為:簡體
Go 再次討論 catch error 模型,官方迴應現狀

Go 再次討論 catch error 模型,官方迴應現狀

  • 爱糖宝
  • 2024-06-19
  • 2087
  • 0
  • 0

最近社羣的同學和 Go 官方又因為錯誤處理的提案屢屢被否,發生了一些小的摩擦。也非常難得的看到核心團隊成員首次表達了目前的態度和情況。

基於此,我們今天進行該內容分享。緊跟 Go 官方最新進展。

快速背景

Go 的錯誤處理機制,主要是依賴於 if err != nil 的方式。因此在對函式做一定的封裝後。

程式碼會呈現出以下樣子:

jy1, err := Foo1()
if err != nil {
    return err
}
jy2, err := Foo2()
if err != nil {
    return err
}
err := Foo3()
if err != nil {
    return err
}
...

有部分開發者會認為這比較的醜陋、混亂且難以閱讀。因此 Go 錯誤處理的最佳化,也是社羣裡一直反覆提及和提出的領域。飽受各類爭議。

新提案:追求類似 try-catch

最近一位國內的同學 @xiaokentrl 提了個類似 try catch error 的新提案,試圖用魔法打敗魔法。

Go 再次討論 catch error 模型,官方迴應現狀

原作者給出的提案內容是:

1、新增環境變數做開關:

ERROR_SINGLE = TRUE   //error_single = true

2、使用特定識別符號來做 try-catch:

Demo1 單行錯誤處理:

//Single-line error handling
file, err := os.Create("abc.txt") @ return nil , err
defer file.Close()

Demo2 多行錯誤處理:

func main() {
    //Multiline error handling
    :@

    file, err:= os.Open("abc.txt")
    defer file.Close()

    buf := make([]byte, 1024)
    _, err2 := file.Read(buf)

    @ err | err2  return ...
}

主要的變化內容是:利用標籤 @ 新增一個類似 try-catch 的程式碼區塊,並新增運算子和相關錯誤處理的聯動規則。

這個提案本身,其實就是以往講到的 goto error 和 check/with 這種類似 try-catch 的模式。

當然非常快的就遭到了 Go 核心團隊的反對:

Go 再次討論 catch error 模型,官方迴應現狀

@Ian Lance Taylor 表示:由於很難處理宣告和應用,如果一個標籤的作用域中還有其他變數,就不能使用 goto。

新的爭端:官方你行你上

社羣中有同學看到這一次次被否的錯誤處理和關聯提案們,深感無奈和無語。他發出了以下的質疑:

“為什麼不讓 Ian Lance Taylor 和/或 Go 核心團隊的其他成員提出改進的錯誤處理框架的初始原型,然後讓 Go 社羣參與進來,為其最終形式做出貢獻呢?Go 中的泛型正是這樣發展到現在的。

如果我們等待 Go 社羣提出最初的原型,我認為我們將永遠不會有改進的 Go 錯誤處理框架,至少在未來幾年內不會。”

但其實很可惜,因為人家真幹過。

Go 核心團隊是有主動提出過錯誤處理的最佳化提案的,提案名為《Proposal: A built-in Go error check function, try》,快速講一下。

以前的程式碼:

f, err := os.Open(filename)
if err != nil {
	return …, err  // zero values for other results, if any
}

應用該提案後的新程式碼:

f := try(os.Open(filename))

try 只能在本身返回錯誤結果的函式中使用,且該結果必須是外層函式的最後一個結果引數。

不過很遺憾,該官方提案,喜提有史以來被否決最多的提案 TOP1:

Go 再次討論 catch error 模型,官方迴應現狀

最終該提案也由於形形色色的意見,最終涼了。感覺也給 Go 核心團隊潑了一盆涼水,因為這是繼 check/handle 後的 try,到目前也沒有新的官方提案了。

Go 官方迴應

本次提及的新提案下,大家的交流愈演愈烈,有種認為就是 Go 核心團隊故意不讓錯誤處理得到更好的改善。

此時 Go 核心團隊的元老之一 @Ian Lance Taylor 站出來發聲,詮釋了目前 Go 團隊對此的態度。這也是首次。

具體內容如下:

Go 再次討論 catch error 模型,官方迴應現狀

“我們願意考慮一個有良好社羣支援的好的錯誤處理提案。

不幸的是,我很遺憾地說,基本上所有新的錯誤處理提案都不好,也沒有社羣支援。例如,這個提案有 10 個反對票,沒有贊成票。我當然會鼓勵人們在廣泛使用這門語言之前,避擴音交錯誤處理提案。

我還鼓勵人們審查早期的提案。它們在這裏:github.com/golang/go/i… 。目前已有 183 個並在不斷增加。

我自己閱讀了每一個。重要的是,請記住,對已被否決提案的微調的新提案也幾乎肯定也會被否決。

並且請記住,我們只會接受一個與現有語言契合良好的提案。例如:這個提案中使用了一個神奇的 @ 符號,這完全不像現有語言中的任何其他東西。

Go 團隊可能會在適當的時候提出一個新的錯誤處理提案。然而,正如其他人所說,我們最好的想法被社羣認為是不可接受的。而且有大量的 Go 程式設計師對現狀表示滿意。”

總結

目前 Go 錯誤處理的情況和困境是比較明確的,很多社羣同學會基於以往已經被否決的舊提案上進行不斷的微改,再不斷提交。

現階段都是被全面否定的,因為即使做了微調,也無法改變提案本身的核心思想。

而 Go 官方自己提出的 check/handle 和 try 提案,在社羣中也被廣大的網友否決了。還獲得了史上最多人否決的提案的位置。

現階段來看,未來 1-3 年內在錯誤處理的最佳化上仍然會繼續僵持。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.