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

Golang異常處理之優(yōu)雅地控制和處理異常

 更新時(shí)間:2023年04月18日 10:29:05   作者:xidianhuihui  
在Golang中,異常處理是非常重要的一部分,能夠有效地控制和處理代碼中的異常情況。通過Golang的異常處理機(jī)制,可以優(yōu)雅地捕獲和處理異常,保障代碼的可靠性和穩(wěn)定性。同時(shí),Golang還提供了豐富的工具和API,幫助開發(fā)者更加輕松地進(jìn)行異常處理

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。

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

使用示例

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é)果如下,第一個(gè)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ā)生在同一個(gè)協(xié)程,那么 recover 是可以捕獲的,如果 panic 和 recover 發(fā)生在不同的協(xié)程,那么 recover 是不可以捕獲的

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

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

性能

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

首先,Golang 在運(yùn)行時(shí)會維護(hù)一個(gè) 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

反而使用panic的性能更好?

安全

另外一個(gè)比較擔(dān)心的點(diǎn)是panic容易導(dǎo)致崩潰,但是如上所示,只要main方法里做好recover,每個(gè)go協(xié)程使用封裝好的帶recover的方法來調(diào)用,其實(shí)并不會有問題

到此這篇關(guān)于Golang異常處理之優(yōu)雅地控制和處理異常的文章就介紹到這了,更多相關(guān)Golang異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Viper處理Go應(yīng)用程序的配置方法

    使用Viper處理Go應(yīng)用程序的配置方法

    Viper是一個(gè)應(yīng)用程序配置解決方案,用于Go應(yīng)用程序,它支持JSON、TOML、YAML、HCL、envfile和Java properties配置文件格式,這篇文章主要介紹了使用Viper處理Go應(yīng)用程序的配置,需要的朋友可以參考下
    2023-09-09
  • Go語言中基本數(shù)據(jù)類型的相互轉(zhuǎn)換詳解

    Go語言中基本數(shù)據(jù)類型的相互轉(zhuǎn)換詳解

    Go在不同類型的變量之間賦值時(shí)需要顯示轉(zhuǎn)換,不能自動轉(zhuǎn)換。這篇文章主要和大家介紹了Go語言中基本數(shù)據(jù)類型的相互轉(zhuǎn)換,感興趣的小伙伴可以了解一下
    2022-10-10
  • Go語言MySQLCURD數(shù)據(jù)庫操作示例詳解

    Go語言MySQLCURD數(shù)據(jù)庫操作示例詳解

    這篇文章主要為大家介紹了Go語言MySQLCURD數(shù)據(jù)庫操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • GoLang RabbitMQ實(shí)現(xiàn)六種工作模式示例

    GoLang RabbitMQ實(shí)現(xiàn)六種工作模式示例

    這篇文章主要介紹了GoLang RabbitMQ實(shí)現(xiàn)六種工作模式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 關(guān)于go-zero服務(wù)自動收集問題分析

    關(guān)于go-zero服務(wù)自動收集問題分析

    這篇文章主要介紹了關(guān)于go-zero服務(wù)自動收集問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 淺談goland導(dǎo)入自定義包時(shí)出錯(一招解決問題)

    淺談goland導(dǎo)入自定義包時(shí)出錯(一招解決問題)

    這篇文章主要介紹了淺談goland導(dǎo)入自定義包時(shí)出錯(一招解決問題),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • GO語言的IO方法實(shí)例小結(jié)

    GO語言的IO方法實(shí)例小結(jié)

    這篇文章主要介紹了GO語言的IO方法實(shí)例小結(jié),Docker的火爆促成了當(dāng)下新興的Go語言人氣的大幅攀升,需要的朋友可以參考下
    2015-10-10
  • Golang中fsnotify包監(jiān)聽文件變化的原理詳解

    Golang中fsnotify包監(jiān)聽文件變化的原理詳解

    Golang提供了一個(gè)強(qiáng)大的fsnotify包,它能夠幫助我們輕松實(shí)現(xiàn)文件系統(tǒng)的監(jiān)控,本文將深入探討fsnotify包的原理,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    在軟件開發(fā)的世界里,數(shù)據(jù)類型轉(zhuǎn)換是一項(xiàng)基礎(chǔ)而重要的技能,尤其在Go語言這樣類型嚴(yán)格的語言中,正確高效地進(jìn)行類型轉(zhuǎn)換對于性能優(yōu)化和代碼質(zhì)量至關(guān)重要,本文給大家介紹了Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換,需要的朋友可以參考下
    2024-02-02
  • Go實(shí)現(xiàn)文件上傳和下載

    Go實(shí)現(xiàn)文件上傳和下載

    這篇文章主要為大家詳細(xì)介紹了Go實(shí)現(xiàn)文件上傳和下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07

最新評論

循化| 札达县| 华容县| 铁力市| 霍州市| 元谋县| 中宁县| 丰顺县| 胶南市| 金昌市| 开原市| 南和县| 长寿区| 喀喇| 陆河县| 巴彦淖尔市| 八宿县| 枞阳县| 读书| 鹤岗市| 长沙市| 同心县| 商南县| 印江| 元氏县| 华阴市| 遂宁市| 婺源县| 利津县| 平罗县| 上虞市| 西城区| 溆浦县| 杭锦旗| 柞水县| 泰来县| 黔西县| 恭城| 石渠县| 久治县| 太仆寺旗|