日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

聊聊Golang飽受爭(zhēng)議的Error

來(lái)源: 責(zé)編: 時(shí)間:2023-11-06 17:20:06 262觀看
導(dǎo)讀一、error是什么?在C中,返回錯(cuò)誤通過(guò)errno.h中的錯(cuò)誤代碼來(lái)表示,比如0代表No error,也就是沒(méi)有錯(cuò)誤;2代表No such file or directory,也就是找不到指定路徑的文件或文件夾;5代表Input/Output error,表示輸入或輸出出現(xiàn)了錯(cuò)誤.

一、error是什么?

在C中,返回錯(cuò)誤通過(guò)errno.h中的錯(cuò)誤代碼來(lái)表示,比如0代表No error,也就是沒(méi)有錯(cuò)誤;2代表No such file or directory,也就是找不到指定路徑的文件或文件夾;5代表Input/Output error,表示輸入或輸出出現(xiàn)了錯(cuò)誤...9WL28資訊網(wǎng)——每日最新資訊28at.com

而在我們最愛(ài)的Golang中,有這樣一個(gè)飽受爭(zhēng)議的error類型,它不是一個(gè)整數(shù),而是一個(gè)接口。9WL28資訊網(wǎng)——每日最新資訊28at.com

package mainimport (    "errors"    "fmt")type name struct {    error string}func (n *name) Error() string {    return fmt.Sprintf("%s : ...", n.error)}func main() {        err := judge(11)    //err := judge(1)    //err := judge(6)    fmt.Println(err)}func judge(num int) error {    if num > 5 && num < 10 {        return errors.New("這個(gè)數(shù)字大于5了..")    }    if num >= 10 {        return fmt.Errorf("%d大于或等于10了...", num)    }    return &name{error: "hello"}}

這是三種可以作為error返回值的方式。errors.New()創(chuàng)建出來(lái)的error類型其實(shí)是errorString結(jié)構(gòu)體。9WL28資訊網(wǎng)——每日最新資訊28at.com

// src/errors/errors.go// New returns an error that formats as the given text.// Each call to New returns a distinct error value even if the text is identical.func New(text string) error { return &errorString{text}}// errorString is a trivial implementation of error.type errorString struct { s string}func (e *errorString) Error() string { return e.s}

所以我們創(chuàng)建的結(jié)構(gòu)體name其實(shí)和errors.New()底層的形式是基本一樣的。9WL28資訊網(wǎng)——每日最新資訊28at.com

而使用的fmt.Errorf其實(shí)是先將字符串格式化然后再調(diào)用errors.New()。9WL28資訊網(wǎng)——每日最新資訊28at.com

二、error引人爭(zhēng)論的點(diǎn)在哪?

在Go中,設(shè)計(jì)者從語(yǔ)言層面要求人們需要明確地處理遇到的錯(cuò)誤,但是因此導(dǎo)致的問(wèn)題也十分明顯,使用Go語(yǔ)言編寫的代碼中err會(huì)到處都是,不過(guò)優(yōu)秀的IDE——Goland能夠解決這個(gè)問(wèn)題,使用Goland能夠?qū)?code style="background-color: rgb(231, 243, 237); padding: 1px 3px; border-radius: 4px; overflow-wrap: break-word; text-indent: 0px; display: inline-block;">err!=nil這段判斷和處理壓縮,不再干擾代碼的閱讀。9WL28資訊網(wǎng)——每日最新資訊28at.com

我本人是不太喜歡Java的try-catch機(jī)制,可能是不太會(huì)用,Go語(yǔ)言官方提到try-catch會(huì)讓代碼變得比較混亂,很多程序員會(huì)胡亂catch異常,導(dǎo)致錯(cuò)誤處理比較冗長(zhǎng)。9WL28資訊網(wǎng)——每日最新資訊28at.com

而Go語(yǔ)言通過(guò)多返回值機(jī)制,讓返回錯(cuò)誤變得很簡(jiǎn)單,并且提供panic和error兩種機(jī)制,感覺(jué)這種機(jī)制更有優(yōu)勢(shì),也看起來(lái)更簡(jiǎn)潔。9WL28資訊網(wǎng)——每日最新資訊28at.com

煎魚大佬之前有博客談到了Go社區(qū)中關(guān)于Go錯(cuò)誤處理的新議題,大家想了解的可以看看:9WL28資訊網(wǎng)——每日最新資訊28at.com

  • Go 錯(cuò)誤處理新思路?用左側(cè)函數(shù)和表達(dá)式:https://juejin.cn/post/7102268049213882398
  • Go try 新提案靠譜嗎?想簡(jiǎn)化錯(cuò)誤處理了 https://juejin.cn/post/7157931922008571940

其實(shí)之前Go社區(qū)中出現(xiàn)過(guò)多種關(guān)于錯(cuò)誤處理的新議題,但是都沒(méi)有被采納...9WL28資訊網(wǎng)——每日最新資訊28at.com

三、如何優(yōu)雅的處理錯(cuò)誤

1. 避免處理“哨兵錯(cuò)誤”,即Sentinel errors

比如為了判斷err == io.EOF就得引入io包,這是標(biāo)準(zhǔn)庫(kù)的包還能接受,如果是第三方庫(kù)的包,并且使用“哨兵錯(cuò)誤”,很容易導(dǎo)致循環(huán)引用的問(wèn)題。9WL28資訊網(wǎng)——每日最新資訊28at.com

2. 避免使用error類型

雖然這種錯(cuò)誤比“哨兵錯(cuò)誤”要好,它可以捕獲更多關(guān)于錯(cuò)誤的上下文信息,比如出錯(cuò)的行數(shù)等其他字段信息。但是又不可避免地在定義錯(cuò)誤和使用錯(cuò)誤的包之間形成依賴關(guān)系,又容易導(dǎo)致循環(huán)引用的問(wèn)題。9WL28資訊網(wǎng)——每日最新資訊28at.com

3. 使用不透明的“黑盒錯(cuò)誤”
func f() error{    sentence,err := say.Hello()    if err != nil{        return err    }    // ...}

上面這種寫法是不是我們經(jīng)常會(huì)用到?這種情況下,我們只需要判斷err是否為空,不為空,代表有錯(cuò)誤,就直接返回錯(cuò)誤,否則就繼續(xù)執(zhí)行后面的流程。9WL28資訊網(wǎng)——每日最新資訊28at.com

作為程序執(zhí)行者,你沒(méi)有能力看到程序錯(cuò)誤的內(nèi)部信息,只能知道程序有錯(cuò)或者沒(méi)有錯(cuò)誤。這種錯(cuò)誤處理作為一種調(diào)試輔助手段還是不錯(cuò)的。9WL28資訊網(wǎng)——每日最新資訊28at.com

4. 使用Warp和Cause

第三方庫(kù)github.com/pkg/errors可以輸出錯(cuò)誤堆棧,并且使用起來(lái)很簡(jiǎn)單,大家可以了解一下。9WL28資訊網(wǎng)——每日最新資訊28at.com

// Wrap annotates cause with a message.func Wrap(cause error, message string) error// Cause unwraps an annotated error.func Cause(err error) error

下面來(lái)介紹Wrap和Cause的使用樣例:9WL28資訊網(wǎng)——每日最新資訊28at.com

func ReadFile(path string) ([]byte, error) {        f, err := os.Open(path)        if err != nil {                return nil, errors.Wrap(err, "open failed")        }        defer f.Close()        buf, err := ioutil.ReadAll(f)        if err != nil {                return nil, errors.Wrap(err, "read failed")        }        return buf, nil}func ReadConfig() ([]byte, error) {        home := os.Getenv("HOME")        config, err := ReadFile(filepath.Join(home, ".settings.xml"))        return config, errors.Wrap(err, "could not read config")}func main() {        _, err := ReadConfig()        if err != nil {                fmt.Println(err)                os.Exit(1)        }}

如果ReadConfig()執(zhí)行失敗,就會(huì)得到下面這一行十分美觀的報(bào)錯(cuò):9WL28資訊網(wǎng)——每日最新資訊28at.com

could not read config: open failed: open /Users/dfc/.settings.xml: no such file or directory

而如果用fmt.Printf和%+v格式來(lái)輸出就能看到更清晰、更有層次的錯(cuò)誤堆棧:9WL28資訊網(wǎng)——每日最新資訊28at.com

func main() {        _, err := ReadConfig()        if err != nil {                fmt.Printf("%+v",err)                os.Exit(1)        }}

圖片圖片9WL28資訊網(wǎng)——每日最新資訊28at.com

然后我們?cè)賮?lái)看Cause的使用。9WL28資訊網(wǎng)——每日最新資訊28at.com

type temporary interface{    Temporary() bool}// IsTemporary returns true if err is temporary.func IsTemporary(err error) bool {        te, ok := errors.Cause(err).(temporary)        return ok && te.Temporary()}

當(dāng)需要檢查一個(gè)錯(cuò)誤與一個(gè)特定的值或類型時(shí)。比如此處,先用Cause取出錯(cuò)誤,做斷言,最后調(diào)用Temporary(),如果斷言失敗,ok就會(huì)是false,就不會(huì)調(diào)用右邊的Temporary()去執(zhí)行。9WL28資訊網(wǎng)——每日最新資訊28at.com

如果 && 運(yùn)算符左側(cè)的子表達(dá)式為 false,則不會(huì)檢查右側(cè)的表達(dá)式。因?yàn)橹灰幸粋€(gè)子表達(dá)式為 false,則整個(gè)表達(dá)式都為 false,所以再檢查剩余的表達(dá)式會(huì)浪費(fèi) CPU 時(shí)間。這被稱為短路評(píng)估。9WL28資訊網(wǎng)——每日最新資訊28at.com

本文轉(zhuǎn)載自微信公眾號(hào)「 程序員升級(jí)打怪之旅」,作者「 丘山子&王中陽(yáng)Go」,可以通過(guò)以下二維碼關(guān)注。9WL28資訊網(wǎng)——每日最新資訊28at.com

9WL28資訊網(wǎng)——每日最新資訊28at.com

轉(zhuǎn)載本文請(qǐng)聯(lián)系「 程序員升級(jí)打怪之旅」公眾號(hào)。9WL28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-17287-0.html聊聊Golang飽受爭(zhēng)議的Error

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 快速了解CSS 相對(duì)顏色

下一篇: 開(kāi)發(fā)微服務(wù)的九個(gè)最佳實(shí)踐

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 阿荣旗| 惠来县| 若尔盖县| 永吉县| 武穴市| 拉萨市| 江安县| 花垣县| 上饶市| 威宁| 三门峡市| 伊川县| 罗甸县| 革吉县| 舞钢市| 确山县| 岐山县| 合水县| 广灵县| 寿光市| 阳原县| 望城县| 中牟县| 扶沟县| 九江市| 鲁山县| 襄城县| 东明县| 体育| 伽师县| 安仁县| 吴桥县| 沧源| 商南县| 长顺县| 大港区| 凭祥市| 公安县| 泸水县| 阳城县| 宣城市|