<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在 Go 語言中,錯誤是可以預期的,并且不是非常嚴重,不會影響程序的運行。對于這類問題,可以用返回錯誤給調用者的方法,讓調用者自己決定如何處理。 在 Go 語言中,錯誤是通過內置的 error 接口表示的。它非常簡單,只有一個 Error 方法用來返回具體的錯誤信息,如下面的代碼所示: **error 接口** ``` type error interface { Error() string } ``` 示例: ``` func main() { i,err:=strconv.Atoi("a") if err!=nil { fmt.Println(err) }else { fmt.Println(i) } } ``` 打印錯誤信息: ``` strconv.Atoi: parsing "a": invalid syntax ``` **自定義錯誤信息** ``` func main() { result, err := div(9,0) if err == nil{ fmt.Println(result) }else{ fmt.Println(err) } } func div(m, n int) (int, error){ if n == 0{ return 0, errors.New("被除數不能為0") } return m/n, nil } ``` **自定義 error** 上面返回錯誤信息的方式只能傳遞一個字符串,也就是攜帶的信息只有字符串,如果想要攜帶更多信息(比如錯誤碼信息)該怎么辦呢?這個時候就需要自定義 error 。 自定義 error 其實就是先自定義一個新類型,比如結構體,然后讓這個類型實現 error 接口,如下面的代碼所示: ``` type commonError struct { errorCode int //錯誤碼 errorMsg string //錯誤信息 } func (err *commonError) Error() string{ return err.errorMsg } ``` 有了自定義的 error,就可以使用它攜帶更多的信息,現在改造上面的例子,返回剛剛自定義的 commonError,如下所示: ``` func div(m, n int) (int, error){ if n == 0{ return 0, &CommonError{1, "被除數不能為0"} } return m/n, nil } ``` **error 斷言** 有了自定義的 error,并且攜帶了更多的錯誤信息后,就可以使用這些信息了。你需要先把返回的 error 接口轉換為自定義的錯誤類型。 ``` func main() { result, err := div(9,0) if ce, ok := err.(*CommonError); !ok{ fmt.Println(result) }else{ fmt.Println("錯誤碼為:", ce.ErrorCode, "錯誤信息為:", ce.ErrorMsg) } } ``` 如果返回的 ok 為 true,說明 error 斷言成功,正確返回了 *commonError 類型的變量 ce,所以就可以像示例中一樣使用變量 ce 的 errorCode 和 errorMsg 字段信息了。 **錯誤嵌套** 基于已經存在的 error 再生成一個 error 比如調用一個函數,返回了一個錯誤信息 error,在不想丟失這個 error 的情況下,又想添加一些額外信息返回新的 error,可以使用自定義 struct 實現 ``` type MyError struct { err error msg string } ``` 這個結構體有兩個字段,其中 error 類型的 err 字段用于存放已存在的 error,string 類型的 msg 字段用于存放新的錯誤信息,這種方式就是 error 的嵌套。 現在讓 MyError 這個 struct 實現 error 接口,然后在初始化 MyError 的時候傳遞存在的 error 和新的錯誤信息,如下面的代碼所示: ``` func (e *MyError) Error() string { return e.err.Error() + e.msg } func main() { //err是一個存在的錯誤,可以從另外一個函數返回 newErr := MyError{err, "數據上傳問題"} } ``` 這種方式可以滿足我們的需求,但是非常煩瑣,因為既要定義新的類型還要實現 error 接口。所以從 Go 語言 1.13 版本開始,Go 標準庫新增了 Error Wrapping 功能,讓我們可以基于一個存在的 error 生成新的 error,并且可以保留原 error 信息,如下面的代碼所示: ```golang e := errors.New("原始錯誤e") w := fmt.Errorf("wrap了一個錯誤:%w", e) fmt.Println(w) // wrap了一個錯誤:原始錯誤e ``` **errors.Unwrap 函數** 既然 error 可以包裹嵌套生成一個新的 error,那么也可以被解開,即通過 errors.Unwrap 函數得到被嵌套的 error。 Go 語言提供了 errors.Unwrap 用于獲取被嵌套的 error,比如以上例子中的錯誤變量 w ,就可以對它進行 unwrap,獲取被嵌套的原始錯誤 e。 ```golang fmt.Println(errors.Unwrap(w)) // 原始錯誤e ``` **errors.Is** 有了 Error Wrapping 后,原來用的判斷兩個 error 是不是同一個 error 的方法失效了,比如 Go 語言標準庫經常用到的如下代碼中的方式: ``` if err == os.ErrExist ``` 為什么會出現這種情況呢?由于 Go 語言的 Error Wrapping 功能,令人不知道返回的 err 是否被嵌套,又嵌套了幾層? 于是 Go 語言為我們提供了 errors.Is 函數,用來判斷兩個 error 是否是同一個,如下所示: ``` func Is(err, target error) bool ``` 以上就是errors.Is 函數的定義,可以解釋為: - 如果 err 和 target 是同一個,那么返回 true。 - 如果 err 是一個 wrapping error,target 也包含在這個嵌套 error 鏈中的話,也返回 true。 ``` func main() { e := errors.New("原始錯誤e") w := fmt.Errorf("wrap了一個錯誤:%w", e) fmt.Println(errors.Is(w,e)) } ``` **errors.As** 同樣的原因,有了 error 嵌套后,error 斷言也不能用了,因為你不知道一個 error 是否被嵌套,又嵌套了幾層。所以 Go 語言為解決這個問題提供了 errors.As 函數,比如前面 error 斷言的例子,可以使用 errors.As 函數重寫,效果是一樣的,如下面的代碼所示: ``` func main() { result, err := div(9, 0) var ce *CommonError if errors.As(err,&ce){ fmt.Println("錯誤代碼為:",ce.ErrorCode,",錯誤信息為:",ce.ErrorMsg) } else { fmt.Println(result) } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看