婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Golang中重復錯誤處理的優化方法

Golang中重復錯誤處理的優化方法

熱門標簽:南通如皋申請開通400電話 江西轉化率高的羿智云外呼系統 高德地圖標注口訣 中國地圖標注省會高清 西部云谷一期地圖標注 地圖標注的汽車標 浙江高速公路地圖標注 廣州呼叫中心外呼系統 學海導航地圖標注

Golang 錯誤處理最讓人頭疼的問題就是代碼里充斥著「if err != nil」,它們破壞了代碼的可讀性,本文收集了幾個例子,讓大家明白如何優化此類問題。

讓我們看看 Errors are values 中提到的一個 io.Writer 例子:

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

如上代碼乍一看無法直觀的看出其本來的意圖是什么,改進版:

type errWriter struct {
 w io.Writer
 err error
}

func (ew *errWriter) write(buf []byte) {
 if ew.err != nil {
 return
 }
 _, ew.err = ew.w.Write(buf)
}

ew := errWriter{w: fd}
ew.write(p0[a:b])
ew.write(p1[c:d])
ew.write(p2[e:f])
if ew.err != nil {
 return ew.err
}

通過自定義類型 errWriter 來封裝 io.Writer,并且封裝了 error,新類型有一個 write 方法,不過其方法簽名并沒有返回 error,而是在方法內部判斷一旦有問題就立刻返回,有了這些準備工作,我們就可以把原本穿插在業務邏輯中間的錯誤判斷提出來放到最后來統一調用,從而在視覺上保證讓人可以直觀的看出代碼本來的意圖是什么。

讓我們再看看 Eliminate error handling by eliminating errors 中提到的另一個 io.Writer 例子:

type Header struct {
 Key, Value string
}

type Status struct {
 Code int
 Reason string
}

func WriteResponse(w io.Writer, st Status, headers []Header, body io.Reader) error {
 _, err := fmt.Fprintf(w, "HTTP/1.1 %d %s\r\n", st.Code, st.Reason)
 if err != nil {
 return err
 }

 for _, h := range headers {
 _, err := fmt.Fprintf(w, "%s: %s\r\n", h.Key, h.Value)
 if err != nil {
 return err
 }
 }

 if _, err := fmt.Fprint(w, "\r\n"); err != nil {
 return err
 }

 _, err = io.Copy(w, body)
 return err
}

第一感覺既然錯誤是 fmt.Fprint 和 io.Copy 返回的,是不是我們要重新封裝一下它們?實際上真正的源頭是它們的參數 io.Writer,因為直接調用 io.Writer 的 Writer 方法的話,方法簽名中有返回值 error,所以每一步 fmt.Fprint 和 io.Copy 操作都不得不進行重復的錯誤處理,看上去是壞味道,改進版:

type errWriter struct {
 io.Writer
 err error
}

func (e *errWriter) Write(buf []byte) (int, error) {
 if e.err != nil {
 return 0, e.err
 }

 var n int
 n, e.err = e.Writer.Write(buf)
 return n, nil
}

func WriteResponse(w io.Writer, st Status, headers []Header, body io.Reader) error {
 ew := errWriter{Writer: w}
 fmt.Fprintf(ew, "HTTP/1.1 %d %s\r\n", st.Code, st.Reason)

 for _, h := range headers {
 fmt.Fprintf(ew, "%s: %s\r\n", h.Key, h.Value)
 }

 fmt.Fprint(ew, "\r\n")
 io.Copy(ew, body)

 return ew.err
}

通過自定義類型 errWriter 來封裝 io.Writer,并且封裝了 error,同時重寫了 Writer 方法,雖然方法簽名中仍然有返回值 error,但是我們單獨保存了一份 error,并且在方法內部判斷一旦有問題就立刻返回,有了這些準備工作,新版的 WriteResponse 不再有重復的錯誤判斷,只需要在最后檢查一下 error 即可。

類似的做法在 Golang 標準庫中屢見不鮮,讓我們繼續看看 Eliminate error handling by eliminating errors 中提到的一個關于 bufio.Reader 和 bufio.Scanner 的例子:

func CountLines(r io.Reader) (int, error) {
 var (
 br = bufio.NewReader(r)
 lines int
 err error
 )

 for {
 _, err = br.ReadString('\n')
 lines++
 if err != nil {
 break
 }
 }

 if err != io.EOF {
 return 0, err
 }

 return lines, nil
}

我們構造一個 bufio.Reader,然后在一個循環中調用 ReadString 方法,如果讀到文件結尾,那么 ReadString 會返回一個錯誤(io.EOF),為了判斷此類情況,我們不得不在每次循環時判斷「if err != nil」,看上去這是壞味道,改進版:

func CountLines(r io.Reader) (int, error) {
 sc := bufio.NewScanner(r)
 lines := 0

 for sc.Scan() {
 lines++
 }

 return lines, sc.Err()
}

實際上,和 bufio.Reader 相比,bufio.Scanner 是一個更高階的類型,換句話簡單點來說的話,相當于是 bufio.Scanner 抽象了 bufio.Reader,通過把低階的 bufio.Reader 換成高階的 bufio.Scanner,循環中不再需要判斷「if err != nil」,因為 Scan 方法簽名不再返回 error,而是返回 bool,當在循環里讀到了文件結尾的時候,循環直接結束,如此一來,我們就可以統一在最后調用 Err 方法來判斷成功還是失敗,看看 Scanner 的定義:

type Scanner struct {
 r   io.Reader // The reader provided by the client.
 split  SplitFunc // The function to split the tokens.
 maxTokenSize int  // Maximum size of a token; modified by tests.
 token  []byte // Last token returned by split.
 buf   []byte // Buffer used as argument to split.
 start  int  // First non-processed byte in buf.
 end   int  // End of data in buf.
 err   error  // Sticky error.
 empties  int  // Count of successive empty tokens.
 scanCalled bool  // Scan has been called; buffer is in use.
 done   bool  // Scan has finished.
}

可見 Scanner 封裝了 io.Reader,并且封裝了 error,和我們之前討論的做法一致。有一點說明一下,實際上查看 Scan 源代碼的話,你會發現它不是通過 err 來判斷是否結束的,而是通過 done 來判斷是否結束,這是因為 Scan 只有遇到文件結束的錯誤才退出,其它錯誤會繼續執行,當然,這只是具體的細節問題,不影響我們的結論。

通過對以上幾個例子的分析,我們可以得出優化重復錯誤處理的大概套路:通過創建新的類型來封裝原本干臟活累活的舊類型,同時在新類型中封裝 error,新舊類型的方法簽名可以保持兼容,也可以不兼容,這個不是關鍵的,視客觀情況而定,至于具體的邏輯實現,先判斷有沒有 error,如果有就直接退出,如果沒有就繼續執行,并且在執行過程中保存可能出現的 error 以便后面操作使用,最后通過統一調用新類型的 error 來完成錯誤處理。提醒一下,此方案的缺點是要到最后才能知道有沒有錯誤,好在如此的控制粒度在多數時候并無大礙。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

您可能感興趣的文章:
  • GO語言標準錯誤處理機制error用法實例
  • Go語言中更優雅的錯誤處理
  • Golang巧用defer進行錯誤處理的方法
  • 詳解Go多協程并發環境下的錯誤處理
  • Go語言中錯誤處理實例分析
  • Go 自定義error錯誤的處理方法
  • 一些關于Go程序錯誤處理的相關建議

標簽:德宏 吐魯番 許昌 貴州 東營 保定 常州 曲靖

巨人網絡通訊聲明:本文標題《Golang中重復錯誤處理的優化方法》,本文關鍵詞  Golang,中,重復,錯誤,處理,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Golang中重復錯誤處理的優化方法》相關的同類信息!
  • 本頁收集關于Golang中重復錯誤處理的優化方法的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久草中文综合在线| 一本久道久久综合中文字幕| 亚洲一卡二卡三卡四卡无卡久久| 精品国产成人系列| 国产亚洲精品资源在线26u| 中文字幕在线免费不卡| 视频一区二区中文字幕| 风流少妇一区二区| 色综合久久综合网欧美综合网| 欧美videos中文字幕| 天堂成人免费av电影一区| 不卡一区中文字幕| 精品久久久久久久人人人人传媒| 亚洲成人午夜影院| 欧美午夜在线一二页| 亚洲最大的成人av| a4yy欧美一区二区三区| 亚洲天堂av一区| 99久久777色| 亚洲欧美国产三级| 欧美天天综合网| 亚洲激情五月婷婷| 欧美性受极品xxxx喷水| 亚洲成人av一区二区| 欧美在线一二三四区| 亚洲已满18点击进入久久| 欧美写真视频网站| 久久精品国产网站| 国产蜜臀97一区二区三区| 成人黄色电影在线| 亚洲一级二级三级在线免费观看| 欧美高清一级片在线| 喷白浆一区二区| 久久精品无码一区二区三区| 国产视频不卡一区| 色哟哟欧美精品| 日韩不卡免费视频| 中文字幕欧美日本乱码一线二线| 在线观看亚洲专区| 美国毛片一区二区| 国产精品久久久久久久裸模| 91丨porny丨首页| 经典三级视频一区| 亚洲精品免费一二三区| 精品毛片乱码1区2区3区| 成人av网址在线| 久久精品国产免费| 亚洲国产成人av| 亚洲欧洲无码一区二区三区| 欧美一区二区网站| 91久久一区二区| 成人av小说网| 精品在线亚洲视频| 亚洲婷婷综合久久一本伊一区 | 国产成人亚洲综合a∨婷婷图片| 亚洲va在线va天堂| 狠狠久久亚洲欧美| 欧美性感一区二区三区| 亚洲色图视频免费播放| www.亚洲人| 国产精品久久久久久久久免费丝袜| 国产成人在线观看免费网站| 久久久久久久久久久99999| 韩日av一区二区| 久久婷婷色综合| 国产成人免费在线观看| 国产精品美女久久久久高潮| 成人免费看片app下载| 亚洲婷婷国产精品电影人久久| 成人精品小蝌蚪| 亚洲乱码中文字幕综合| 欧美日韩一区三区四区| 日韩**一区毛片| 久久久久亚洲综合| 99久久久无码国产精品| 亚洲日本va午夜在线影院| 欧美亚洲国产一区二区三区| 日韩中文字幕一区二区三区| 日韩亚洲欧美一区| 国产精品一区二区在线观看不卡 | 午夜亚洲国产au精品一区二区| 欧美亚洲高清一区| 日本vs亚洲vs韩国一区三区二区| 91精品国产综合久久香蕉的特点| 麻豆国产欧美日韩综合精品二区| 精品捆绑美女sm三区| 国产美女娇喘av呻吟久久| 中文字幕一区二区三区在线播放 | 岛国一区二区在线观看| 亚洲天堂2016| 日韩欧美123| 91蜜桃在线免费视频| 奇米精品一区二区三区在线观看| 久久久www成人免费无遮挡大片| 一本久久精品一区二区| 精品亚洲免费视频| 亚洲激情五月婷婷| 337p日本欧洲亚洲大胆精品| 在线免费观看视频一区| 国产精品伊人色| 日韩av中文字幕一区二区三区| 日本一二三四高清不卡| 欧美丰满嫩嫩电影| 色综合天天综合给合国产| 国产一区二区三区在线观看精品| 亚洲成人激情综合网| 中文字幕在线不卡| 欧美精品一区二区三区高清aⅴ| 91在线国内视频| 国产精品77777| 日本不卡视频在线| 亚洲一区二区高清| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | www国产精品av| 欧美区视频在线观看| 成人福利电影精品一区二区在线观看| 日本伊人色综合网| 一区二区三国产精华液| 久久精品视频在线看| 欧美一区二区在线视频| 91黄视频在线观看| 91亚洲大成网污www| 国产精品1024| 国内外成人在线视频| 美女一区二区久久| 秋霞电影一区二区| 日本午夜精品视频在线观看| 亚洲夂夂婷婷色拍ww47| 国产精品妹子av| 欧美激情在线观看视频免费| 精品免费国产一区二区三区四区| 777午夜精品免费视频| 欧美日韩第一区日日骚| 在线日韩一区二区| 欧洲一区在线观看| 在线观看亚洲a| 欧美综合在线视频| 91九色02白丝porn| 欧美综合一区二区三区| 精品污污网站免费看| 欧美日韩三级在线| 欧美日韩一区二区三区在线| 欧美日韩另类一区| 欧美伦理电影网| 91精品国产综合久久久久久久 | 偷窥少妇高潮呻吟av久久免费| 亚洲福利一区二区| 亚洲成人免费看| 日韩成人av影视| 精品一区二区三区欧美| 国内外成人在线视频| 国产高清亚洲一区| 成人精品视频网站| 色域天天综合网| 欧美性猛交xxxx黑人交| 欧美猛男男办公室激情| 91麻豆精品国产| 欧美va在线播放| 日本一区二区成人| 一区二区三区在线免费播放| 婷婷激情综合网| 韩国三级中文字幕hd久久精品| 国产精品自拍av| 不卡电影免费在线播放一区| 色婷婷综合在线| 欧美一级欧美三级在线观看| 欧美精品一区二区蜜臀亚洲| 中文字幕在线一区| 午夜久久久久久久久久一区二区| 日韩国产在线观看一区| 精品一区二区三区免费毛片爱| 成人黄色综合网站| 欧美日本一区二区三区四区| 精品国产乱码久久久久久久| 中文字幕在线不卡| 奇米影视7777精品一区二区| 成人动漫视频在线| 欧美久久婷婷综合色| 久久人人爽人人爽| 亚洲国产成人av| 成人晚上爱看视频| 7777精品久久久大香线蕉| 国产农村妇女毛片精品久久麻豆| 亚洲综合色噜噜狠狠| 国产精品一品视频| 欧美日韩视频在线第一区| 日本一区二区三区电影| 日日夜夜精品视频天天综合网| 国产成人av一区二区三区在线| 欧美伊人久久久久久久久影院| 26uuu亚洲综合色| 亚洲高清视频在线| 波多野结衣一区二区三区 | 日韩欧美成人一区二区| 一区二区在线观看视频在线观看| 蜜桃91丨九色丨蝌蚪91桃色| 在线观看亚洲精品| 中文字幕精品—区二区四季| 麻豆精品久久精品色综合| 欧洲一区二区av|