欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在Go中創(chuàng)建自定義錯誤的方式總結

 更新時間:2024年01月16日 14:51:28   作者:CHQIUU  
在程序開發(fā)中錯誤處理是至關重要的,下面這篇文章主要給大家介紹了關于在Go中創(chuàng)建自定義錯誤的方式,文中通過代碼介紹的非常詳細,對大家學習或者使用Go具有一定的參考借鑒價值,需要的朋友可以參考下

引言

Go提供了兩種在標準庫中創(chuàng)建錯誤的方法,[errors.Newfmt.Errorf],當與用戶交流更復雜的錯誤信息時,或在調試時與未來的自己交流時,有時這兩種機制不足以充分捕獲和報告所發(fā)生的情況。為了傳達更復雜的錯誤信息并實現(xiàn)更多的功能,我們可以實現(xiàn)標準庫接口類型,error。

其語法如下:

type error interface {
  Error() string
}

builtin包將error定義為一個接口,它只有一個Error()方法,返回一個字符串形式的錯誤消息。通過實現(xiàn)這個方法,我們可以將定義的任何類型轉換為我們自己的error。

讓我們嘗試運行以下示例來查看error接口的實現(xiàn):

package main

import (
	"fmt"
	"os"
)

type MyError struct{}

func (m *MyError) Error() string {
	return "boom"
}

func sayHello() (string, error) {
	return "", &MyError{}
}

func main() {
	s, err := sayHello()
	if err != nil {
		fmt.Println("unexpected error: err:", err)
		os.Exit(1)
	}
	fmt.Println("The string:", s)
}
Outputunexpected error: err: boom
exit status 1

在這里,我們創(chuàng)建了一個新的空結構類型MyError,并在其上定義了Error()方法。Error()方法返回字符串"boom"。

main()中,我們調用函數(shù)sayHello,該函數(shù)返回一個空字符串和一個新的MyError實例。由于sayHello總是會返回錯誤,所以main()中的if語句體中的fmt.Println調用總是會執(zhí)行。然后,我們使用fmt.Println打印短前綴字符串"unexpected error:"以及err變量中保存的MyError實例。

請注意,我們不必直接調用Error(),因為fmt包能夠自動檢測這是Error 的實現(xiàn)。它透明地調用Error()來獲取字符串"boom",并將其與前綴字符串"unexpected Error: err:"連接起來。

在自定義錯誤中收集詳細信息

有時候,自定義錯誤是捕獲詳細錯誤信息的最簡潔方式。例如,假設我們想要捕獲HTTP請求產(chǎn)生的錯誤的狀態(tài)碼;運行以下程序來查看error的實現(xiàn),它允許我們清晰地捕獲信息:

package main

import (
	"errors"
	"fmt"
	"os"
)

type RequestError struct {
	StatusCode int

	Err error
}

func (r *RequestError) Error() string {
	return fmt.Sprintf("status %d: err %v", r.StatusCode, r.Err)
}

func doRequest() error {
	return &RequestError{
		StatusCode: 503,
		Err:        errors.New("unavailable"),
	}
}

func main() {
	err := doRequest()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	fmt.Println("success!")
}

Outputstatus 503: err unavailable
exit status 1

在這個例子中,我們創(chuàng)建了一個新的RequestError實例,并使用標準庫中的errors.New函數(shù)提供狀態(tài)碼和一個錯誤。然后像前面的例子一樣,我們使用fmt.Println打印它。

RequestErrorError()方法中,我們使用fmt.Sprintf函數(shù)來使用創(chuàng)建錯誤時提供的信息來構造一個字符串。

類型斷言和自定義錯誤

error接口只公開了一個方法,但我們可能需要訪問error實現(xiàn)的其他方法來正確處理錯誤。例如,我們可能有幾個臨時的error自定義實現(xiàn),可以通過存在的 temporary()方法進行檢索。

接口為類型提供了更廣泛的方法集合,因此我們必須使用類型斷言來更改view正在顯示的方法,或者完全刪除它。

下面的例子在之前的RequestError的基礎上增加了一個Temporary()方法,該方法將表明調用者是否應該重試請求:

package main

import (
	"errors"
	"fmt"
	"net/http"
	"os"
)

type RequestError struct {
	StatusCode int

	Err error
}

func (r *RequestError) Error() string {
	return r.Err.Error()
}

func (r *RequestError) Temporary() bool {
	return r.StatusCode == http.StatusServiceUnavailable // 503
}

func doRequest() error {
	return &RequestError{
		StatusCode: 503,
		Err:        errors.New("unavailable"),
	}
}

func main() {
	err := doRequest()
	if err != nil {
		fmt.Println(err)
		re, ok := err.(*RequestError)
		if ok {
			if re.Temporary() {
				fmt.Println("This request can be tried again")
			} else {
				fmt.Println("This request cannot be tried again")
			}
		}
		os.Exit(1)
	}

	fmt.Println("success!")
}

Outputunavailable
This request can be tried again
exit status 1

main()中,我們調用doRequest(),它會返回一個error接口給我們。我們首先打印 error()方法返回的錯誤消息。接下來,我們嘗試使用類型斷言re, ok := err.(*RequestError)來暴露RequestError中的所有方法。如果類型斷言成功,那么我們使用Temporary()方法來查看此錯誤是否為臨時錯誤。由于doRequest()設置的StatusCode503,這與http.StatusServiceUnavailable匹配,因此返回true并導致打印" this request can be try again"。在實踐中,我們會發(fā)送另一個請求,而不是打印一條消息。

包裝錯誤

通常,錯誤會在程序之外產(chǎn)生,例如:數(shù)據(jù)庫、網(wǎng)絡連接等。這些錯誤提供的錯誤消息不能幫助任何人找到錯誤的根源。在錯誤消息的開頭使用額外的信息包裝錯誤,可以為成功調試提供一些必要的上下文。

下面的例子演示了我們如何將一些上下文信息附加到從其他函數(shù)返回的晦澀的error上:

package main

import (
	"errors"
	"fmt"
)

type WrappedError struct {
	Context string
	Err     error
}

func (w *WrappedError) Error() string {
	return fmt.Sprintf("%s: %v", w.Context, w.Err)
}

func Wrap(err error, info string) *WrappedError {
	return &WrappedError{
		Context: info,
		Err:     err,
	}
}

func main() {
	err := errors.New("boom!")
	err = Wrap(err, "main")

	fmt.Println(err)
}

Outputmain: boom!

WrappedError是一個有兩個字段的結構體:一個是string類型的上下文消息,另一個是error類型,WrappedError提供了更多的信息。當Error()方法被調用時,我們再次使用fmt.Sprintf來打印上下文消息,然后Error(fmt.Sprintf也知道隱式調用Error()方法)。

main()中,我們使用errors.New創(chuàng)建一個錯誤,然后使用我們定義的wrap函數(shù)包裝這個錯誤。這允許我們指出這個error是在"main"中生成的。此外,由于我們的WrappedError也是一個error,我們可以包裝其他的WrappedError,這將允許我們看到一個鏈來幫助我們追蹤錯誤的來源。在標準庫的幫助下,我們甚至可以在錯誤中嵌入完整的堆棧跟蹤。

總結

由于error接口只有一個方法,我們已經(jīng)看到我們可以為不同的情況提供不同類型的錯誤。這可以涵蓋從將多條信息作為錯誤的一部分進行溝通到實現(xiàn)指數(shù)回退的所有事情。雖然Go中的錯誤處理機制表面上看起來很簡單,但我們可以使用這些自定義錯誤來處理常見和不常見的情況,從而實現(xiàn)相當豐富的處理。

Go還有另一種溝通意外行為的機制panics。在錯誤處理系列的下一篇文章中,我們將研究恐慌——它們是什么以及如何處理它們。

到此這篇關于在Go中創(chuàng)建自定義錯誤的文章就介紹到這了,更多相關Go創(chuàng)建自定義錯誤內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • go中的參數(shù)傳遞是值傳遞還是引用傳遞的實現(xiàn)

    go中的參數(shù)傳遞是值傳遞還是引用傳遞的實現(xiàn)

    參數(shù)傳遞機制是一個重要的概念,它決定了函數(shù)內部對參數(shù)的修改是否會影響到原始數(shù)據(jù),本文主要介紹了go中的參數(shù)傳遞是值傳遞還是引用傳遞的實現(xiàn),感興趣的可以了解一下
    2024-12-12
  • 如何go語言比較兩個對象是否深度相同

    如何go語言比較兩個對象是否深度相同

    這篇文章主要介紹了如何go語言比較兩個對象是否深度相同,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • Golang空接口與類型斷言的實現(xiàn)

    Golang空接口與類型斷言的實現(xiàn)

    本文主要介紹了Golang空接口與類型斷言的實現(xiàn),文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • go for range坑和閉包坑的分析

    go for range坑和閉包坑的分析

    今天小編就為大家分享一篇關于go for range坑和閉包坑的分析,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Go初學者踩坑之go?mod?init與自定義包的使用

    Go初學者踩坑之go?mod?init與自定義包的使用

    go?mod是go的一個模塊管理工具,用來代替?zhèn)鹘y(tǒng)的GOPATH方案,下面這篇文章主要給大家介紹了關于Go初學者踩坑之go?mod?init與自定義包的使用,需要的朋友可以參考下
    2022-10-10
  • 解決goland新建項目文件名為紅色的問題

    解決goland新建項目文件名為紅色的問題

    這篇文章主要介紹了解決goland新建項目文件名為紅色的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 使用Go構建一款靜態(tài)分析工具Owl詳解

    使用Go構建一款靜態(tài)分析工具Owl詳解

    Owl是一款開源項目依賴分析工具,可以快速在指定的項目目錄下查找符合某些特征的源代碼文件或者依賴文件,這篇文章主要介紹了使用Go構建一款靜態(tài)分析工具,需要的朋友可以參考下
    2022-06-06
  • Go開源項目分布式唯一ID生成系統(tǒng)

    Go開源項目分布式唯一ID生成系統(tǒng)

    這篇文章主要為大家介紹了Go開源項目分布式唯一ID生成系統(tǒng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • go語言實現(xiàn)并發(fā)網(wǎng)絡爬蟲的示例代碼

    go語言實現(xiàn)并發(fā)網(wǎng)絡爬蟲的示例代碼

    本文主要介紹了go語言實現(xiàn)并發(fā)網(wǎng)絡爬蟲的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • go實現(xiàn)限流功能示例

    go實現(xiàn)限流功能示例

    這篇文章主要為大家介紹了go實現(xiàn)限流功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08

最新評論