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

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

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

panic和recover使用

Go語言不支持傳統(tǒng)的 try…catch…finally 這種異常,因為Go語言的設(shè)計者們認(rèn)為,將異常與控制結(jié)構(gòu)混在一起會很容易使得代碼變得混亂。在Go語言中,設(shè)計者們推薦使用多值返回來返回錯誤。遇到真正的異常的情況下(比如除數(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其實就是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時,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的幾點擔(dān)心

性能

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

首先,Golang 在運行時會維護(hù)一個 panic 堆,用于存儲棧中的 panic 對象。當(dāng)程序遇到 panic 時,會將該 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的性能更好?

安全

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

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

相關(guān)文章

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

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

    Viper是一個應(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在不同類型的變量之間賦值時需要顯示轉(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實現(xiàn)六種工作模式示例

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論

华蓥市| 贞丰县| 江川县| 鄂伦春自治旗| 青神县| 名山县| 长沙市| 清丰县| 宾阳县| 城固县| 元谋县| 漳平市| 法库县| 永昌县| 黔江区| 杭锦后旗| 玉屏| 和顺县| 勐海县| 洞头县| 新竹市| 铅山县| 江城| 广丰县| 台湾省| 阳东县| 滨州市| 长葛市| 华亭县| 涪陵区| 怀安县| 醴陵市| 易门县| 通州区| 定安县| 芜湖市| 开阳县| 宁晋县| 上杭县| 万安县| 常德市|