日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
一文掌握Golang中Panic與Recover的作用和使用方法

panic

panic作用是終止當(dāng)前正在運(yùn)行的程序(包括所有協(xié)程)并輸出導(dǎo)致異常的堆棧信息。在遇到無(wú)法處理的異常情況時(shí),例如比如數(shù)組越界、操作未初始化的map、空指針等都會(huì)觸發(fā)panic。主動(dòng)觸發(fā)panic示例:

package main   
  
func main() {  
    // 未處理的自定義異常  
    customException := "an error occurred"   
    panic(customException)  
}

會(huì)輸出如下信息:

panic: an error occurred

goroutine 1 [running]:
main.main()
        /Users/ning/projects/go/workspace/hello/panic/main.go:7 +0x34

Process finished with the exit code 2

數(shù)據(jù)越界導(dǎo)致panic示例:

package main

import "fmt"

func main() {
	a := [2]int{4, 5}
	fmt.Println(a[3])
}

會(huì)輸出如下信息:

# command-line-arguments
./main.go:11:16: invalid argument: array index 3 out of bounds [0:2]

Compilation finished with exit code 2

recover

recover可以讓觸發(fā)了panic的程序繼續(xù)運(yùn)行,recover僅在延遲函數(shù)defer中有效,在正常的執(zhí)行過(guò)程中,調(diào)用recover會(huì)返回nil并且不產(chǎn)生其他任何效果。如果當(dāng)前的goroutine觸發(fā)了panic,調(diào)用recover可以捕獲到panic的輸入值,并且恢復(fù)正常運(yùn)行。這個(gè)特性對(duì)于像web服務(wù)就非常有用了, 當(dāng)web服務(wù)處理某個(gè)請(qǐng)求時(shí),某個(gè)方法觸發(fā)了panic,這時(shí)候顯然是不應(yīng)該直接讓web服務(wù)掛掉的。這種場(chǎng)景下,就可以使用recover來(lái)捕獲panic并且讓服務(wù)正常運(yùn)行下去。

在其他語(yǔ)言里,通常是底層拋出異常,上層邏輯通過(guò)try/catch捕獲異常。defer/panic/recover配合使用可以實(shí)現(xiàn)類(lèi)似try/catch的功能。

將Recover()寫(xiě)在defer中,在可能發(fā)生panic的代碼之前執(zhí)行defer,當(dāng)程序觸發(fā)panic后,系統(tǒng)將跳過(guò)后面的代碼,按照逆序執(zhí)行已經(jīng)注冊(cè)的defer函數(shù),如果defer函數(shù)中調(diào)用了recover(),recover()會(huì)返回捕獲到的panic的錯(cuò)誤信息。

使用recover需要注意幾點(diǎn):

  • recover需要在defer的方法里面直接調(diào)用,不能對(duì)recover()包一層方法后再在defer的方法里面調(diào)用
  • recover只能捕獲同一個(gè)協(xié)程中的panic,無(wú)法捕獲其它協(xié)程的panic

defer/panic/recover示例

成功捕獲實(shí)例一

func main() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("recover:%v\n", err)
		}
	}()
	panic("an error occurred")
}

成功捕獲實(shí)例二

func main() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("recover:%v\n", err)
		}
	}()
	test()
}

func test() {
	panic("an error occurred")
}

成功捕獲實(shí)例三

func main() {
	test()
}

func test() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("recover:%v\n", err)
		}
	}()
	panic("an error occurred")
}

不能捕獲實(shí)例一

func main() {
	if err := recover(); err != nil {
		fmt.Printf("recover:%v\n", err)
	}
	panic("an error occurred")
}

不能捕獲實(shí)例二

func main() {
	go func() {
		defer func() {
			if err := recover(); err != nil {
				fmt.Printf("recover:%v\n", err)
			}
		}()
	}()
	panic("an error occurred")
}

不能捕獲實(shí)例三

func main() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("recover:%v\n", err)
		}
	}()

	go test()

	for {
		select {}
	}
}

func test() {
	panic("an error occurred")
}

不能捕獲實(shí)例四

func main() {
	defer func() {
		recoverFromPanic()
	}()

	test()
}

func recoverFromPanic() {
	if err := recover(); err != nil {
		fmt.Printf("recover:%v\n", err)
	}
}

func test() {
	panic("an error occurred")
}

不能捕獲實(shí)例五

func main() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("recover:%v\n", err)
		}
	}()

	test()

	for {
		select {}
	}
}

func test() {
	go func() {
		panic("an error occurred")
	}()
}

小結(jié)

本文介紹了panic和recover的作用及使用方法,以及defer/panic/recover配合使用實(shí)現(xiàn)類(lèi)似try/catch的功能,下篇文章將從源碼角度來(lái)做講解。


當(dāng)前題目:一文掌握Golang中Panic與Recover的作用和使用方法
鏈接分享:http://m.5511xx.com/article/cojogde.html