溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Golang異??刂铺幚沓绦蝈e誤流程是什么

發(fā)布時(shí)間:2023-05-06 15:34:35 來源:億速云 閱讀:125 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Golang異??刂铺幚沓绦蝈e誤流程是什么”,在日常操作中,相信很多人在Golang異??刂铺幚沓绦蝈e誤流程是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Golang異常控制處理程序錯誤流程是什么”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

    panic和recover使用

    Go語言不支持傳統(tǒng)的 try…catch…finally 這種異常,因?yàn)镚o語言的設(shè)計(jì)者們認(rèn)為,將異常與控制結(jié)構(gòu)混在一起會很容易使得代碼變得混亂。在Go語言中,設(shè)計(jì)者們推薦使用多值返回來返回錯誤。遇到真正的異常的情況下(比如除數(shù)為 0了)。才使用Go中引入的Exception處理:defer, panic, recover。

    這幾個異常的使用場景可以這么簡單描述:Go中可以拋出一個panic的異常,然后在defer中通過recover捕獲這個異常,然后正常處理

    使用示例

    package main
    import "fmt"
    func main(){
        fmt.Println("c")
         defer func(){ // 必須要先聲明defer,否則不能捕獲到panic異常
            fmt.Println("d")
            if err:=recover();err!=nil{
                fmt.Println(err) // 這里的err其實(shí)就是panic傳入的內(nèi)容,55
            }
            fmt.Println("e")
        }()
        f() //開始調(diào)用f
        fmt.Println("f") //這里開始下面代碼不會再執(zhí)行
    }
    func f(){
        fmt.Println("a")
        panic("異常信息")
        fmt.Println("b") //這里開始下面代碼不會再執(zhí)行
        fmt.Println("f")
    }

    輸出結(jié)果:

    c
    a
    d
    異常信息
    e

    注意

    • 利用recover處理panic指令,recover需要定義在defer匿名函數(shù)內(nèi)

    • defer需要在panic之前聲明,否則當(dāng)panic時(shí),recover無法捕獲到panic

    • panic無recover情況下,程序會直接崩潰

    子函數(shù)panic主函數(shù)recover

    func TestPanic(t *testing.T) {
    	defer func() {
    		if err := recover(); err != nil {
    			println("recovered")
    		}
    	}()
    	subFun()
    	subFun()
    }
    func subFun() {
    	println("subFun")
    	panic("subFun panic")
    }

    輸出結(jié)果如下,第一個sunFun后面的代碼不會執(zhí)行

    subFun
    recovered

    子協(xié)程panic主函數(shù)recover

    func subFun(i int) {
    	fmt.Println("subFun,i=", i)
    	panic("subFun panic")
    }
    func TestSubGoPanic(t *testing.T) {
    	defer func() {
    		if err := recover(); err != nil {
    			println("recovered2")
    		}
    	}()
    	go subFun(3)
    	subFun(4)
    	println("finish")
    }

    結(jié)果
    subFun,i= 4
    recovered2
    subFun,i= 3
    --- PASS: TestSubGoPanic (0.00s)
    panic: subFun panic

    goroutine 21 [running]:
    zh.com/base/err.subFun(0x0?)
        /Users/albert/file/code/go/zh/gotest/base/err/panic_test.go:34 +0x89
    created by zh.com/base/err.TestSubGoPanic
        /Users/albert/file/code/go/zh/gotest/base/err/panic_test.go:43 +0x46

    recover會執(zhí)行,但是程序崩潰了

    使用總結(jié)

    如果 panic 和 recover 發(fā)生在同一個協(xié)程,那么 recover 是可以捕獲的,如果 panic 和 recover 發(fā)生在不同的協(xié)程,那么 recover 是不可以捕獲的

    也就是哪個協(xié)程有panic,哪個協(xié)程里必須要有recover,否則會把整個程序弄崩潰

    使用panic的幾點(diǎn)擔(dān)心

    性能

    在使用 Golang 進(jìn)行開發(fā)時(shí),遇到 panic 是非常常見的情況。但是,panic 對于性能的影響是相對較小的,尤其是在實(shí)際使用中。

    首先,Golang 在運(yùn)行時(shí)會維護(hù)一個 panic 堆,用于存儲棧中的 panic 對象。當(dāng)程序遇到 panic 時(shí),會將該 panic 對象添加到 panic 堆中。panic 堆的大小是有限的,如果堆中的對象過多,可能會導(dǎo)致 panic 堆溢出,從而影響程序的性能

    性能對比

    func BenchmarkSubFunWithError(b *testing.B) {
    	for i := 0; i < b.N; i++ {
    		go subFunWithError(i)
    	}
    }
    func BenchmarkSubFunWithRecover(b *testing.B) {
    	for i := 0; i < b.N; i++ {
    		go subFunWithRecover(i)
    	}
    }
    func subFunWithRecover(i int) {
    	//fmt.Println("subFun,i=", i)
    	defer func() {
    		if error := recover(); error != nil {
    			//println("subFunWithRecover_recovered")
    		}
    	}()
    	time.Sleep(time.Second)
    	panic("subFun panic")
    }
    func subFunWithError(i int) error {
    	//fmt.Println("subFun,i=", i)
    	time.Sleep(time.Second)
    	return errors.New("subFunWithError")
    }
    BenchmarkSubFunWithError-12               673920              1992 ns/op             489 B/op          3 allocs/op
    BenchmarkSubFunWithRecover-12            1000000              1229 ns/op             240 B/op          2 allocs/op

    到此,關(guān)于“Golang異常控制處理程序錯誤流程是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI