最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入探究Go語(yǔ)言的錯(cuò)誤策略與異常機(jī)制

 更新時(shí)間:2024年02月03日 09:37:39   作者:鼠鼠我捏,要死了捏  
本文深入探討了Go語(yǔ)言的錯(cuò)誤策略與異常機(jī)制,主要介紹了錯(cuò)誤處理的重要性,以及Go語(yǔ)言中的錯(cuò)誤類型和處理函數(shù),此外還討論了Go語(yǔ)言的異常機(jī)制,包括panic和recover函數(shù)的使用,需要的朋友可以參考下

前言

作為開發(fā)者來(lái)說(shuō),我們沒(méi)辦法保證程序在運(yùn)行過(guò)程中永遠(yuǎn)不會(huì)出現(xiàn)異常,對(duì)于異常,在很多編程語(yǔ)言中,可以用 try-catch語(yǔ)句來(lái)捕獲,而Go語(yǔ)言的開發(fā)者顯然覺得 try-catch被濫用了,因此 Go不支持使用 try-catch語(yǔ)句捕獲異常處理。

那么,Go語(yǔ)言是如何定義和處理程序的異常呢?

Go語(yǔ)言的將程序運(yùn)行出現(xiàn)的問(wèn)題分為兩種:錯(cuò)誤(error)和異常(exception),錯(cuò)誤是程序(比如一個(gè)函數(shù))運(yùn)行的預(yù)期結(jié)果之一,當(dāng)你調(diào)用一個(gè)函數(shù)時(shí),就應(yīng)該處理出現(xiàn)錯(cuò)誤的情況,而異常是不可預(yù)期的(當(dāng)然也可以手動(dòng)觸發(fā))且會(huì)導(dǎo)致程序中斷運(yùn)行的嚴(yán)重錯(cuò)誤。

Go錯(cuò)誤處理策略

編寫Go語(yǔ)言程序,一般推薦通過(guò)函數(shù)的最后一個(gè)返回值告訴調(diào)用者函數(shù)是否執(zhí)行成功,可以分兩種情況來(lái)討論:

第一種情況,如果函數(shù)的執(zhí)行結(jié)果只有正確與失敗,那么返回值可以是 boolean類型:

func exists(key string) bool {
	//to check if the key is exists
	return true
}
 
if ok := exists("test"); ok {
	// do something
}

第二種情況,如果要讓調(diào)用者得到更詳細(xì)的錯(cuò)誤信息,顯然只返回一個(gè)布爾值是不夠的,這時(shí)候可以返回一個(gè) error類型,error類型是一個(gè)接口,只有一個(gè) Error方法的接口:

type error interface {
	Error() string
}

通過(guò) error類型的 Error方法,可以獲得更詳細(xì)的錯(cuò)誤信息,方便調(diào)用者做進(jìn)一步的處理,因此在 Go標(biāo)準(zhǔn)庫(kù)的方法和函數(shù)中,一般都會(huì)將 error類型作為最后一個(gè)返回值,比如我們以前文章中講到的 os包下的 Open和 Create函數(shù):

package os
 
func Open(name string) (*File, error) {
	return OpenFile(name, O_RDONLY, 0)
}
 
func Create(name string) (*File, error) {
	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}

當(dāng)函數(shù)最后一個(gè)返回值 error不為 nil時(shí),表示執(zhí)行不成功,此時(shí)其他的返回值就應(yīng)該忽略:

file,err := os.Open("./my.dat")
 
if err != nil{
  	return err
}
 
defer file.Close()

上面代碼中,如果 error不為 nil,那么變量 file則為 nil,表示無(wú)法獲得一個(gè)文件句柄,這時(shí)候直接返回錯(cuò)誤,因?yàn)槿绻倮^續(xù)往下執(zhí)行,可能會(huì)引發(fā)程序崩潰。

當(dāng)然并不是所有情況下一遇到返回的 error不為 nil,就要拋棄其他返回值,比如使用 Read()方法讀取文件時(shí):

Read(p []byte) (n int, err error)

在讀取文件到結(jié)尾時(shí) Read方法會(huì)返回一個(gè) io.EOF的錯(cuò)誤:

var EOF = errors.New("EOF")

此時(shí)雖然 error不為 nil,但仍然應(yīng)該把讀取到的字節(jié)數(shù)組保存,而不是拋棄掉。

創(chuàng)建error的幾種方式

當(dāng)我們開發(fā)自己的函數(shù)時(shí),也可以創(chuàng)建自己的錯(cuò)誤類型,有以下幾種方式:

errors包

errors包下的 New()函數(shù)可以創(chuàng)建一個(gè)只有文本信息的 error類型:

package main
 
func main() {
	var s = []int{1, 2, 3}
	s[3] = 10
}

fmt包

fmt包下的 Errorf函數(shù)可以將文本格式后作為error類型的錯(cuò)誤信息,并返回一個(gè)error類型,因此其作用與errors.New函數(shù)類似

func getFile(name string)(*os.file,error){
	if name == ""{
		return nil,fmt.Errorf("file name could not be empty")
	}
}

fmt.Errorf函數(shù)還能封裝其他 error類型,再返回一個(gè)新的 error類型,以此形成一條完整的錯(cuò)誤鏈條:

doc, err := html.Parse(resp.Body)
resp.Body.Close()
if err != nil {
	return nil, fmt.Errorf("parsing %s as HTML: %v", url,err)
}

自定義錯(cuò)誤類型

其實(shí),上面兩種創(chuàng)建錯(cuò)誤類型的方式,本質(zhì)上都是實(shí)現(xiàn) error接口,我們也可以創(chuàng)建一個(gè)擁有 Error方法的類型來(lái)實(shí)現(xiàn) error接口:

type Result struct {
	Code    int
	Message string
	Data    interface{}
}
 
func (r Result) Error() string {
	return r.Message
}

如何處理錯(cuò)誤

當(dāng)調(diào)用的函數(shù)或方法的返回值有 error類型時(shí),最簡(jiǎn)單的當(dāng)然可以選擇直接忽略錯(cuò)誤,不過(guò)更恰當(dāng)?shù)姆绞绞翘幚韺?duì)應(yīng)的錯(cuò)誤,有以下幾種處理策略:

直接返回錯(cuò)誤

對(duì)于函數(shù)來(lái)說(shuō),如果在執(zhí)行時(shí)遇到錯(cuò)誤,可以直接返回給上層調(diào)用者:

func SendMessage(url string) error {
	if url == ""{
		return errors.New("url can't not be empty")
	}
	_, err := http.Get(url)
	if err != nil {
		return err
	}
	return nil
}

記錄日志并繼續(xù)運(yùn)行

當(dāng)調(diào)用函數(shù)時(shí)遇到返回的錯(cuò)誤,如果不影響程序運(yùn)行,也可以選擇記錄錯(cuò)誤日志并往下執(zhí)行:

if err := SendMessage("https://xxx/sendMessage");err != nil{
	log.Printf("the message sending been broken by : %v\n", err)
}
 

記錄日志并結(jié)束運(yùn)行

如果錯(cuò)誤影響程序的執(zhí)行,也可以記錄日志后,退出程序執(zhí)行:

if err := SendMessage("https://xxx/sendMessage");err != nil{
	log.Printf("the message sending been broken by : %v\n", err)
	os.Exit(1)
}

記錄日志并退出執(zhí)行,直接用 log包的 Fatalf函數(shù)就可以做到,因此上面代碼的更簡(jiǎn)潔做法是:

if err := SendMessage("https://xxx/sendMessage");err != nil{
	log.Fatalf("the message sending been broken by : %v\n", err)
}

Go異常處理機(jī)制

在Go語(yǔ)言中,異常是指會(huì)引發(fā)程序崩潰無(wú)法繼續(xù)運(yùn)行的錯(cuò)誤,比如數(shù)組越界或者空指針引用等情況,這時(shí)候會(huì)觸發(fā) panic異常:

package main
 
func main() {
	var s = []int{1, 2, 3}
	s[3] = 10
}

上面程序運(yùn)行結(jié)果如下,可以看出觸發(fā)了數(shù)組越界的異常:

panic: runtime error: index out of range [3] with length 3

無(wú)論是在主協(xié)程還是子協(xié)程中,一旦觸發(fā) panic異常,整個(gè)程序都會(huì)終止運(yùn)行。

panic函數(shù)

除了數(shù)組越界等不可預(yù)測(cè)的異常會(huì)自動(dòng)觸發(fā) panic,也可以手動(dòng)調(diào)用 panic函數(shù)觸發(fā)異常來(lái)終止程序的運(yùn)行:

func loadConfig(path string){
	panic("can't load the config file on path " + path)
}

一個(gè)良好的程序最好不要主動(dòng)調(diào)用 panic函數(shù),尤其是開發(fā)類庫(kù)的時(shí)候,最好通過(guò)返回 error類型來(lái)告訴調(diào)用者發(fā)生了什么錯(cuò)誤,而不是觸發(fā) panic導(dǎo)致程序終止運(yùn)行。

recover函數(shù)

當(dāng)發(fā)生 panic異常時(shí),如果不捕獲得異常,那么程序就是終止運(yùn)行,在Go語(yǔ)言中,可以用 defer語(yǔ)句和 recover函數(shù)的模式來(lái)捕獲 panic異常:

package main
 
import (
	"fmt"
	"log"
)
 
func main() {
 
	n1 := FindElementByIndex(1)
	fmt.Println(n1)
  
	n2 := FindElementByIndex(4)
	fmt.Println(n2)
}
 
func FindElementByIndex(index int) int {
	defer func() {
		if e := recover(); e != nil {
			log.Fatal(e)
		}
	}()
	s := []int{1, 2, 3, 4}
	return s[index]
}
 

總結(jié)

本文深入探討了Go語(yǔ)言的錯(cuò)誤策略與異常機(jī)制。主要介紹了錯(cuò)誤處理的重要性,以及Go語(yǔ)言中的錯(cuò)誤類型和處理函數(shù)。此外還討論了Go語(yǔ)言的異常機(jī)制,包括panic和recover函數(shù)的使用。通過(guò)合理的錯(cuò)誤處理和異常處理,我們可以提高代碼的可維護(hù)性和可靠性,減少潛在的bug和故障。希望本文對(duì)您有幫助,感謝閱讀~

以上就是深入探究Go語(yǔ)言的錯(cuò)誤策略與異常機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于Go錯(cuò)誤策略與異常機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • go?集成nacos注冊(cè)中心、配置中心的過(guò)程詳解

    go?集成nacos注冊(cè)中心、配置中心的過(guò)程詳解

    這篇文章主要介紹了go集成nacos注冊(cè)中心、配置中心的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-12-12
  • Go語(yǔ)言消息序列化 JSON、ProtoBuf與MsgPack對(duì)比

    Go語(yǔ)言消息序列化 JSON、ProtoBuf與MsgPack對(duì)比

    本文對(duì)比了三種序列化方式的特點(diǎn)和Go語(yǔ)言實(shí)現(xiàn),開發(fā)者應(yīng)根據(jù)具體場(chǎng)景選擇合適的序列化方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-05-05
  • 詳解Go語(yǔ)言中for循環(huán),break和continue的使用

    詳解Go語(yǔ)言中for循環(huán),break和continue的使用

    這篇文章主要通過(guò)一些示例為大家介紹一下Go語(yǔ)言中for循環(huán)、break和continue的基本語(yǔ)法以及使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-06-06
  • Go語(yǔ)言格式化動(dòng)詞使用詳解

    Go語(yǔ)言格式化動(dòng)詞使用詳解

    這篇文章主要介紹了Go語(yǔ)言格式化動(dòng)詞使用詳解的相關(guān)資料,需要的朋友可以參考下
    2023-08-08
  • 一文帶你搞懂golang中內(nèi)存分配逃逸分析

    一文帶你搞懂golang中內(nèi)存分配逃逸分析

    這篇文章主要帶大家一起學(xué)習(xí)一下golang中內(nèi)存分配逃逸分析,文中的示例代碼講解詳細(xì),對(duì)我們深入了解golang有一定的幫助,感興趣的小伙伴可以了解下
    2023-08-08
  • 解決Go gorm踩過(guò)的坑

    解決Go gorm踩過(guò)的坑

    這篇文章主要介紹了解決Go gorm踩過(guò)的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Go語(yǔ)言中實(shí)現(xiàn)多線程定時(shí)任務(wù)的示例代碼

    Go語(yǔ)言中實(shí)現(xiàn)多線程定時(shí)任務(wù)的示例代碼

    本文主要介紹了Go語(yǔ)言中實(shí)現(xiàn)多線程定時(shí)任務(wù)的示例代碼,使用goroutine和channel實(shí)現(xiàn)輕量級(jí)線程及通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • Go語(yǔ)言實(shí)現(xiàn)23種設(shè)計(jì)模式的使用

    Go語(yǔ)言實(shí)現(xiàn)23種設(shè)計(jì)模式的使用

    設(shè)計(jì)模式是軟件工程中各種常見問(wèn)題的經(jīng)典解決方案,,本文主要介紹了Go語(yǔ)言實(shí)現(xiàn)23種設(shè)計(jì)模式的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 詳解Go?依賴管理?go?mod?tidy

    詳解Go?依賴管理?go?mod?tidy

    這篇文章主要為大家介紹了詳解Go?依賴管理?go?mod?tidy,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • golang中的select關(guān)鍵字用法總結(jié)

    golang中的select關(guān)鍵字用法總結(jié)

    這篇文章主要介紹了golang中的select關(guān)鍵字用法總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06

最新評(píng)論

玉林市| 宁都县| 浮山县| 景德镇市| 巴林右旗| 印江| 同江市| 老河口市| 麟游县| 蒲城县| 昭苏县| 晴隆县| 合作市| 繁昌县| 金湖县| 长丰县| 泾川县| 喜德县| 黄石市| 神木县| 邓州市| 科技| 武功县| 阜新| 宜昌市| 清苑县| 兴义市| 贵州省| 神木县| 文化| 永济市| 肥城市| 临夏市| 阿合奇县| 德庆县| 平安县| 西青区| 马公市| 仁布县| 安西县| 松溪县|