這篇文章將為大家詳細(xì)講解有關(guān)怎么在Golang中處理重復(fù)錯(cuò)誤,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
目前創(chuàng)新互聯(lián)公司已為上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、赤坎網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。_, 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 }
如上代碼乍一看無(wú)法直觀的看出其本來(lái)的意圖是什么,改進(jìn)版:
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 }
通過(guò)自定義類型 errWriter 來(lái)封裝 io.Writer,并且封裝了 error,新類型有一個(gè) write 方法,不過(guò)其方法簽名并沒(méi)有返回 error,而是在方法內(nèi)部判斷一旦有問(wèn)題就立刻返回,有了這些準(zhǔn)備工作,我們就可以把原本穿插在業(yè)務(wù)邏輯中間的錯(cuò)誤判斷提出來(lái)放到最后來(lái)統(tǒng)一調(diào)用,從而在視覺(jué)上保證讓人可以直觀的看出代碼本來(lái)的意圖是什么。
讓我們?cè)倏纯?Eliminate error handling by eliminating errors 中提到的另一個(gè) 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 }
第一感覺(jué)既然錯(cuò)誤是 fmt.Fprint 和 io.Copy 返回的,是不是我們要重新封裝一下它們?實(shí)際上真正的源頭是它們的參數(shù) io.Writer,因?yàn)橹苯诱{(diào)用 io.Writer 的 Writer 方法的話,方法簽名中有返回值 error,所以每一步 fmt.Fprint 和 io.Copy 操作都不得不進(jìn)行重復(fù)的錯(cuò)誤處理,看上去是壞味道,改進(jìn)版:
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 }
通過(guò)自定義類型 errWriter 來(lái)封裝 io.Writer,并且封裝了 error,同時(shí)重寫(xiě)了 Writer 方法,雖然方法簽名中仍然有返回值 error,但是我們單獨(dú)保存了一份 error,并且在方法內(nèi)部判斷一旦有問(wèn)題就立刻返回,有了這些準(zhǔn)備工作,新版的 WriteResponse 不再有重復(fù)的錯(cuò)誤判斷,只需要在最后檢查一下 error 即可。
類似的做法在 Golang 標(biāo)準(zhǔn)庫(kù)中屢見(jiàn)不鮮,讓我們繼續(xù)看看 Eliminate error handling by eliminating errors 中提到的一個(gè)關(guān)于 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 }
我們構(gòu)造一個(gè) bufio.Reader,然后在一個(gè)循環(huán)中調(diào)用 ReadString 方法,如果讀到文件結(jié)尾,那么 ReadString 會(huì)返回一個(gè)錯(cuò)誤(io.EOF),為了判斷此類情況,我們不得不在每次循環(huán)時(shí)判斷「if err != nil」,看上去這是壞味道,改進(jìn)版:
func CountLines(r io.Reader) (int, error) { sc := bufio.NewScanner(r) lines := 0 for sc.Scan() { lines++ } return lines, sc.Err() }
實(shí)際上,和 bufio.Reader 相比,bufio.Scanner 是一個(gè)更高階的類型,換句話簡(jiǎn)單點(diǎn)來(lái)說(shuō)的話,相當(dāng)于是 bufio.Scanner 抽象了 bufio.Reader,通過(guò)把低階的 bufio.Reader 換成高階的 bufio.Scanner,循環(huán)中不再需要判斷「if err != nil」,因?yàn)?Scan 方法簽名不再返回 error,而是返回 bool,當(dāng)在循環(huán)里讀到了文件結(jié)尾的時(shí)候,循環(huán)直接結(jié)束,如此一來(lái),我們就可以統(tǒng)一在最后調(diào)用 Err 方法來(lái)判斷成功還是失敗,看看 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. }
golang可以做服務(wù)器端開(kāi)發(fā),但golang很適合做日志處理、數(shù)據(jù)打包、虛擬機(jī)處理、數(shù)據(jù)庫(kù)代理等工作。在網(wǎng)絡(luò)編程方面,它還廣泛應(yīng)用于web應(yīng)用、API應(yīng)用等領(lǐng)域。
關(guān)于怎么在Golang中處理重復(fù)錯(cuò)誤就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
文章題目:怎么在Golang中處理重復(fù)錯(cuò)誤-創(chuàng)新互聯(lián)
網(wǎng)站路徑:http://aaarwkj.com/article4/dddeie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、App開(kāi)發(fā)、小程序開(kāi)發(fā)、網(wǎng)站策劃、用戶體驗(yàn)、移動(dòng)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容