日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Errors are values

發布時間:2025/6/17 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Errors are values 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文地址?https://blog.golang.org/errors-are-values

Go程序員之間(特別是這些剛接觸Go語言的新人)一個常見的討論點是如何處理錯誤。談話經常變成為對如下代碼序列出現次數的感嘆。

If err!=nil{

??return err

}

我們最近掃描了我們可以找到的所有開源項目,并發現這個代碼段每頁或每兩頁只出現一次,比你相信的要少。然而,如果這種看法仍然存在:所有時候都必須輸入

If err!=nil

一定有些地方是錯誤的,明顯的目標就是Go本身。

?

這是不幸的,誤導的,很容易糾正的。也許正在發生的事情是新的程序員問道“如何處理錯誤?”,學習這種模式,并停止在那里。在其他語言中,可能會使用try-catch塊或其他這樣的機制來處理錯誤。因此,程序員認為,當我用舊的語言使用try-catch時,我將在Go中輸入err=nil。隨著時間的推移,Go代碼收集了很多這樣的片段,結果感覺很笨拙。

無論這個解釋是否合適,很明顯,這些Go程序員錯過了關于errors的基本觀點:錯誤是值(Errors are values

值可編程,并且由于錯誤是值,所以可以對錯誤進行編程。

當然,一個涉及錯誤值的常見語句是測試它是否為nil,但是還有無數的其他東西可以使用錯誤值,并且應用某些其他的東西可以使你的程序更好,消除了大量樣板(如果每個error通過一個死記硬背的if語句來判斷)。

這是一個簡單的例子,來自bufio包的Scanner類型。它的Scan方法執行底層I/O,這當然可能導致錯誤。然而Scan方法根本不會顯示錯誤。相反,它返回一個布爾值,并且在掃描結束時用一個單獨的方法報告是否發生錯誤。客戶端代碼如下所示:

scanner := bufio.NewScanner(input)

for scanner.Scan() {

????token := scanner.Text()

????// process token

}

if err := scanner.Err(); err != nil {

????// process the error

}

?

當然,這里有個對errnil檢查,但它似乎只執行一次。Scan方法可以被定義為

func (s *Scanner) Scan() (token []byte, error)

?

然后示例用戶代碼可能如下:(取決于如何取得token

scanner := bufio.NewScanner(input)

for {

????token, err := scanner.Scan()

????if err != nil {

????????return err // or maybe break

????}

????// process token

}

?

這不是很大的不同,但有一個重要的區別。在此代碼中,客戶端必須在每次迭代時檢查錯誤,但在實際的Scan API中,將錯誤處理從關鍵的API元素中抽象出來,在token上迭代。使用真實的API,客戶端代碼感覺更自然:循環直到完成,然后判斷錯誤。錯誤處理不會干擾控制流。

?看內部發生了什么,當然是,一旦Scan遇到I/O錯誤,它會記錄它并返回false。一個單獨的方法Err會在客戶端詢問時報告錯誤值。簡而言之,這與把 if err != nil放到任何地方或要求客戶端在每個token后檢查錯誤的做法是不一樣的。它是用錯誤值進行編程。簡單的編程,是的,但仍然編程。

值得強調的是,無論設計如何,程序檢查errors是非常重要的,然而它們是暴露出來的。這里的討論不是關于如何避免檢查錯誤,它是關于使用語言來優雅地處理錯誤。

?

當我在東京參加2014年秋天的GoCon時,出現了重復性錯誤檢查代碼的主題。一個熱心的gopher,在Twitter上的@jxck_,回應了熟悉的關于錯誤檢查的感嘆。他有一些代碼看起來像這樣:

_, err = fd.Write(p0[a:b])

if err != nil {

????return err

}

_, err = fd.Write(p1[c:d])

if err != nil {

????return err

}

_, err = fd.Write(p2[e:f])

if err != nil {

????return err

}

// and so on

這是非常重復的。在真正的代碼中(更長的),有更多的,所以使用一個helper函數重構是不容易的,但是在這種理想的形式中,一個關于錯誤變量的函數將有幫助

?

var err error

write := func(buf []byte) {

????if err != nil {

????????return

????}

????_, err = w.Write(buf)

}

write(p0[a:b])

write(p1[c:d])

write(p2[e:f])

// and so on

if err != nil {

????return err

}

這個模式運作良好,但是需要在每個執行寫入操作的函數中有一個閉包;一個單獨的helper函數使用起來是笨拙的,因為err變量需要在調用之間保持。

?

我們可以通過借用Scan方法的想法來使這個更整潔,更通用和可重用。我在討論中提到了這種技術,但是@jxck_沒有看懂如何應用它。經過長時間的交流,收到語言障礙的阻礙,我問道我是否可以借用他的筆記本電腦,并通過鍵入一些代碼來給他看。

我定義了一個名為errWrite的對象,如下所示:

type errWriter struct {

????w ??io.Writer

????err error

}

?

并給它一個方法,write。它不需要具有標準的Write簽名,小寫部分來突出顯示區別。write方法調用底層WriterWrite方法,并記錄第一個錯誤以供將來參考:

?

func (ew *errWriter) write(buf []byte) {

????if ew.err != nil {

????????return

????}

????_, ew.err = ew.w.Write(buf)

}

?

一旦發生錯誤,寫入方法將變為無效,但是會保存錯誤值。

給出errWrite類型及其寫入方法,可以重構以上代碼:

?

ew=errWriter {wfd}

ew.writep0 [ab]

ew.writep1 [cd]

ew.writep2 [ef]

// 等等

如果ew.err= nil {

???? 返回ew.err

}

?

這更干凈,甚至與使用閉包相比,也使得實際的寫入序列在頁面上更容易看到。沒有任何雜亂。使用錯誤值(和接口)編程使代碼更好。

?

同一個軟件包中的其他一些代碼很可能會建立在這個想法上,甚至直接使用errWriter

?

另外,一旦errWriter存在,還有更多的可以幫助,特別是在較少人為的例子中。它可以累加字節數。它可以將寫入合并到單個緩沖區,然后可以原子傳輸。以及更多。

?

實際上,這種模式經常出現在標準庫中。Archive/zipnet/http包使用它。這個討論更為突出,bufio包的Writer實際上是一個errWriter想法的實現。雖然bufio.Writer.Write返回一個error,這主要是關于遵守io.Writer接口的形式。bufio.WriterWrite方法與上面的errWrite.write方法是一樣,Flush報告錯誤,所以我們的例子可以這樣寫:

b := bufio.NewWriter(fd)

b.Write(p0[a:b])

b.Write(p1[c:d])

b.Write(p2[e:f])

// and so on

if b.Flush() != nil {

????return b.Flush()

}

?

這種方法有一個明顯的缺點,至少對于某些應用程序:無法知道錯誤發生之前完成了多少處理。如果這些信息很重要,則需要采用更細粒度的方法。通常,盡管如此,一個在末尾的完全或沒有檢查就足夠了。

?

我們只看了一種避免重復錯誤處理代碼的技術。請記住,使用errWrite或者bufio.Writer不是簡化錯誤處理的唯一方法,而且這種方法不適用于所有情況。然而,重要的教訓是errors是值,Go編程語言的全部功能可用于處理它們。

使用語言來簡化錯誤處理。

?

但記住:無論你做什么,總是檢查你的errors

?

最后,關于我與@jxck_互動的完整故事,包括他錄制的一點視頻,請訪問他的博客。?

?

轉載于:https://www.cnblogs.com/majianguo/p/6793152.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Errors are values的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。