成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 官方錯(cuò)誤處理討論:用 ? 替代 if err != nil 可以不?

開發(fā) 前端
今天我們給大家?guī)?lái)了 Go 核心團(tuán)隊(duì)的錯(cuò)誤處理新提案,老大哥 @Ian Lance Taylor 基于 Rust 的問號(hào)操作符作為靈感,設(shè)計(jì)出了 Go 的問號(hào)操作符和塊的聯(lián)動(dòng)機(jī)制。

大家好,我是煎魚。

對(duì)于 Go 這一門編程語(yǔ)言,截至目前較大爭(zhēng)議話題仍在 if err != nil 在 Go 應(yīng)用里所帶來(lái)的各種繁雜代碼,引起了社區(qū)很多正反方的探討。

原本以為 Go 核心團(tuán)隊(duì)已經(jīng)擺爛了。但最近老大哥 @Ian Lance Taylor 提出了一個(gè)新提案[1](后轉(zhuǎn)為討論[2]),引起了大量的社區(qū)交流:

圖片圖片

背景:為什么還要關(guān)注這件事?

在 Go 核心團(tuán)隊(duì)的視野中,現(xiàn)階段對(duì)于處理 Go 錯(cuò)誤處理的動(dòng)力,個(gè)人理解至少來(lái)源于以下幾個(gè)主要原因,不斷地推動(dòng)他們看到這件事。

第一是:社區(qū)中用代碼反饋?zhàn)疃嗟模簿褪窃诂F(xiàn)在的 Go 應(yīng)用代碼中,存在較多的 if err != nil 的相關(guān)代碼:

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
 }
}

一堆的 if err != nil 代碼。

第二是:在歷年的 Go 開發(fā)人員調(diào)查報(bào)告中提示 “錯(cuò)誤處理被列為人們今天使用的最大特定挑戰(zhàn)”。

如下圖所示:

圖片圖片

在調(diào)查結(jié)果中,有提到:“在封閉問題中,回答最多的是學(xué)習(xí)如何有效地編寫 Go(15%)和錯(cuò)誤處理的冗長(zhǎng)(13%)。”

第三是:在 Go issues 中存在大量的 Go 錯(cuò)誤處理的各類提案,例如:

圖片圖片

  • 《proposal: Go 2: onerr return[3]》
  • 《proposal: Go 2: add or err: statement after function calls for error handling[4]》
  • 《proposal: Go 2: Use ?variable simplify handling of multiple-return-values[5]》

太多太多太多這類提案了。我也分享過很多腦洞很大的社區(qū)錯(cuò)誤新提案。

新提案:? 新語(yǔ)法

這種新語(yǔ)法的部分靈感來(lái)源于:Rust 的問號(hào)運(yùn)算符。

? 將會(huì)吸收函數(shù)返回的錯(cuò)誤,并在錯(cuò)誤不為 nil 時(shí)自動(dòng)返回,這與之前的 try 的提議類似。

它的不同之處在于:? 是一個(gè)顯式語(yǔ)法元素,而不是對(duì)預(yù)先聲明函數(shù)的調(diào)用,而且 ? 只能出現(xiàn)在語(yǔ)句的末尾,不能出現(xiàn)在表達(dá)式的中間。

基本介紹

例如,原本的 Go 錯(cuò)誤處理代碼如下:

r, err := SomeFunction()
 if err != nil {
  return fmt.Errorf("something failed: %v", err)
 }

新提案引入新的 ? 語(yǔ)法,將其改寫為如下:

r := SomeFunction() ? {
  return fmt.Errorf("something failed: %v", err)
 }

當(dāng)然。如果是另外一種原本的寫法:

if err := SomeFunction2(); err != nil {
  return fmt.Errorf("something else failed: %v", err)
 }

也依然可以改寫為:

SomeFunction2() ? {
  return fmt.Errorf("something else failed: %v", err)
 }

? 這個(gè)用法將會(huì)吸收函數(shù)的錯(cuò)誤結(jié)果。它引入了一個(gè)新塊,如果錯(cuò)誤結(jié)果不為 nil,則執(zhí)行該塊塊。

在新塊中,fmt.Errorf 里的標(biāo)識(shí)符 err 指的是上述吸收的錯(cuò)誤結(jié)果。也就是當(dāng)塊跟在 ? 后面時(shí),它會(huì)隱式聲明一個(gè)新的 err 變量。

完整例子

func Run() error {
 Start() ? // returns error from Start if not nil
 Wait() ?  // returns error from Wait if not nil
 return nil
}
func CopyFile(src, dst string) error {
 r := os.Open(src) ? {
  return fmt.Errorf("copy %s %s: %v", src, dst, err)
 }
 defer r.Close()

 w := os.Create(dst) ? {
  return fmt.Errorf("copy %s %s: %v", src, dst, err)
 }

 io.Copy(w, r) ? {
  w.Close()
  os.Remove(dst)
  return fmt.Errorf("copy %s %s: %v", src, dst, err)
 }

 w.Close() ? {
  os.Remove(dst)
  return fmt.Errorf("copy %s %s: %v", src, dst, err)
 }
}
func MustOpen(n string) *os.File {
 f := os.Open(n) ? {
  panic(err)
 }
 return f
}
func TestFileData(t *testing.T) {
 f := os.Open("testfile") ? {
  t.Fatal(err)
 }
 ...
}
func CreateIfNotExist(name string) error {
 f, err := os.OpenFile(name, os.O_EXCL|os.O_WRONLY, 0o666)
 if errors.Is(err, fs.ErrExist) {
  return nil
 }
 err ? // returns err if it is not nil
 // write to f ...
}

社區(qū)爭(zhēng)論

Go 錯(cuò)誤處理機(jī)制這事,一向是正反雙方都有。有支持繼續(xù)保持的,也有反對(duì)的。

其中一位社區(qū)同學(xué) @Michael Fridman 直接掏出了 Go 創(chuàng)始人 @Rob Pike 的演講 PPT 語(yǔ)錄:

圖片

該位同學(xué)表示:這一提議的優(yōu)點(diǎn)有限 -- 它增加了另一種做事的方式,并使代碼更難閱讀(具有諷刺意味的是)。

其真心希望谷歌不會(huì)不惜一切代價(jià)發(fā)展 Go 語(yǔ)言,因?yàn)檫@將損害 Go 的長(zhǎng)期用戶對(duì) Go 的喜愛。

并且表示:“讓我們保持 Go 的簡(jiǎn)單和無(wú)趣”

總結(jié)

今天我們給大家?guī)?lái)了 Go 核心團(tuán)隊(duì)的錯(cuò)誤處理新提案,老大哥 @Ian Lance Taylor 基于 Rust 的問號(hào)操作符作為靈感,設(shè)計(jì)出了 Go 的問號(hào)操作符和塊的聯(lián)動(dòng)機(jī)制。

關(guān)于 Go 的錯(cuò)誤處理機(jī)制,我經(jīng)歷很多。見到各種人做封裝,還有使用 pnaic+recover 來(lái)做 error 機(jī)制的。各種方法都有。誰(shuí)都不服誰(shuí)。

但是目前 Go1 還是陷入了一個(gè)非常尷尬的境地,有人希望改,有人不希望改。無(wú)論如何都難以 “討好” 全部人。

接下來(lái)就看新上任的 Go 核心團(tuán)隊(duì)負(fù)責(zé)人的魄力如何了。能否像以前 rsc 力推 module 一樣背負(fù)罵名且用力推進(jìn)。

畢竟,@Ian Lance Taylor 能提出這個(gè)提案和討論。很有可能就是內(nèi)部先討論過的了。

參考資料

[1]提案: https://github.com/golang/go/issues/71203

[2]討論: https://github.com/golang/go/discussions/71460

[3]proposal: Go 2: onerr return: https://github.com/golang/go/issues/32848

[4]proposal: Go 2: add or err: statement after function calls for error handling: https://github.com/golang/go/issues/33029

[5]proposal: Go 2: Use ?variable simplify handling of multiple-return-values: https://github.com/golang/go/issues/33074

責(zé)任編輯:武曉燕 來(lái)源: 腦子進(jìn)煎魚了
相關(guān)推薦

2020-12-17 06:25:05

Gopanic 模式

2024-06-05 08:47:20

Go語(yǔ)言方式

2023-03-10 08:48:29

2014-11-17 10:05:12

Go語(yǔ)言

2021-04-29 09:02:44

語(yǔ)言Go 處理

2022-07-13 08:53:28

函數(shù)Go語(yǔ)言

2022-08-01 08:48:39

Go代碼接口

2025-06-05 02:25:00

2024-02-28 08:54:57

switchGo錯(cuò)誤

2022-05-26 08:53:47

Go函數(shù)代碼

2024-03-14 09:35:54

Go 錯(cuò)誤select代碼

2025-06-06 06:45:54

2022-06-13 07:03:25

Go 語(yǔ)言怎么優(yōu)化重

2021-09-13 07:53:31

Go錯(cuò)誤處理

2025-03-31 00:29:44

2022-09-05 08:55:15

Go2提案語(yǔ)法

2025-06-30 09:49:11

2024-03-27 08:18:02

Spring映射HTML

2025-03-31 08:57:25

Go程序性能

2021-09-27 15:33:48

Go 開發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩欧美一区在线 | 国产av毛片 | 久久欧美高清二区三区 | 日韩三区在线 | 亚洲www啪成人一区二区麻豆 | 美日韩中文字幕 | 激情久久网 | 精品免费国产一区二区三区 | 亚洲综合视频 | 中文在线播放 | av免费在线观看网站 | 精品无码久久久久久久动漫 | 国产精品久久久久一区二区三区 | 久久国产精品视频免费看 | 国产在线观看一区二区 | 日韩免费毛片 | 91久久精品国产91久久性色tv | 欧美精品久久久久 | 日韩精品在线播放 | 久操福利| 久草精品在线 | 久久精品国产一区二区三区不卡 | 亚洲精品免费在线观看 | 精品九九 | 国内自拍偷拍一区 | 欧美在线一区二区三区 | 亚洲国产精品成人久久久 | 亚洲精品电影网在线观看 | 麻豆视频在线免费观看 | 午夜视频网站 | 日本韩国电影免费观看 | 91精品国产91久久综合桃花 | 久久一区二区av | aa级毛片毛片免费观看久 | 欧美日韩专区 | 午夜码电影| 亚洲国产精品一区二区第一页 | 午夜视频网站 | 欧美视频在线播放 | 亚洲在线中文字幕 | 91精品国产综合久久久久久首页 |