欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

GoLang中panic與recover函數(shù)以及defer語句超詳細(xì)講解

 更新時(shí)間:2023年01月11日 08:31:06   作者:鯤鵬飛九萬里  
這篇文章主要介紹了GoLang的panic、recover函數(shù),以及defer語句,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

一、運(yùn)行時(shí)恐慌panic

panic是一種在運(yùn)行時(shí)拋出來的異常。比如"index of range"。

panic的詳情:

package main
import "fmt"
func main() {
	oneC := []int{1, 2, 3, 4, 5}
	v5 := oneC[5]
	fmt.Println(v5)
}

$ go run demo01.go
panic: runtime error: index out of range [5] with length 5

goroutine 1 [running]:
main.main()
    /Users/lifei/Documents/workspace/githubRepositoies/gowp/projects/go-core-example/src/article19/q1/demo01.go:7 +0x1b
exit status 2
$

打印信息的第一行,"panic: "右邊的內(nèi)容,正是panic包含的runtime.Error類型值的字符串表示形式;

“goroutine 1 [running]” 表示有一個(gè)id為 1 的 goroutine在此panic被引發(fā)的時(shí)候正在運(yùn)行;

這里的ID編號(hào)并不重要,是GO語言運(yùn)行時(shí)系統(tǒng)內(nèi)部給予的一個(gè)goroutine編號(hào),我們?cè)诔绦蛑袩o法獲取,也無法改變。

再下面是指出哪一行發(fā)生錯(cuò)誤。“+0x1b”代表 此行代碼相對(duì)于其所屬函數(shù)的入口程序計(jì)數(shù)偏移量, 一般用途不大。

最后的 “exit status 2”,表明我的這個(gè)程序是以退出狀態(tài)碼2結(jié)束運(yùn)行的。

在大多操作系統(tǒng)中,只要退出狀態(tài)碼不是0,都意味著程序運(yùn)行的非正常結(jié)束。

二、panic被引發(fā)到程序終止經(jīng)歷的過程

某個(gè)函數(shù)無疑觸發(fā)了panic:

  • 初始的panic詳情會(huì)被建立起來,此行代碼所屬函數(shù)的執(zhí)行隨機(jī)終止。
  • 控制權(quán)立刻轉(zhuǎn)移到上一級(jí);
  • 控制權(quán)如此一層層沿著調(diào)用棧的反方向傳播至頂端,也就是我們編寫的最外層函數(shù);
  • 最終,控制權(quán)被GO語言運(yùn)行時(shí)系統(tǒng)收回。隨后程序崩潰并終止運(yùn)行;

panic 詳情會(huì)在控制權(quán)傳播的過程中,被逐漸地積累和完善,并且,控制權(quán)會(huì)一級(jí)一級(jí)地沿著調(diào)用棧的反方向傳播至頂端。因此,在針對(duì)某個(gè) goroutine 的代碼執(zhí)行信息中,調(diào)用棧底端的信息會(huì)先出現(xiàn),然后是上一級(jí)調(diào)用的信息,以此類推,最后才是此調(diào)用棧頂端的信息。

三、有意引發(fā)一個(gè)panic并讓panic包含一個(gè)值

  • 可以使用panic函數(shù)有意地引發(fā)一個(gè) panic。
  • 在調(diào)用panic函數(shù)時(shí),把某個(gè)值作為參數(shù)傳給該函數(shù)就可以了。由于panic函數(shù)的唯一一個(gè)參數(shù)是空接口(也就是interface{})類型的,所以從語法上講,它可以接受任何類型的值。
  • 但是,我們最好傳入error類型的錯(cuò)誤值,或者其他的可以被有效序列化的值。這里的“有效序列化”指的是,可以更易讀地去表示形式轉(zhuǎn)換。

打印錯(cuò)誤信息:

  • 對(duì)于fmt包下的各種打印函數(shù)來說,error類型值的Error方法與其他類型值的String方法是等價(jià)的,它們的唯一結(jié)果都是string類型的;
  • 如果某個(gè)值有可能會(huì)被記到日志里,那么就應(yīng)該為它關(guān)聯(lián)String方法。

四、施加應(yīng)對(duì)panic的保護(hù)措施從而避免程序崩潰

聯(lián)用defer語句和recover函數(shù)調(diào)用,才能夠恢復(fù)一個(gè)已經(jīng)發(fā)生的 panic。

GO語言的內(nèi)建函數(shù)recover專門用于恢復(fù)panic。recover函數(shù)無需任何參數(shù),并且會(huì)返回一個(gè)空接口類型的值。

defer 語句用來延遲執(zhí)行代碼。延遲到該語句所在的函數(shù)即將執(zhí)行結(jié)束的那一刻,無論結(jié)束執(zhí)行的原因是什么。

限制:有一些調(diào)用表達(dá)式是不能出現(xiàn)在這里的,包括:針對(duì) Go 語言內(nèi)建函數(shù)的調(diào)用表達(dá)式,以及針對(duì)unsafe包中的函數(shù)的調(diào)用表達(dá)式。

package main
import (
	"errors"
	"fmt"
)
func main() {
	fmt.Println("Enter function main")
	// 延遲func函數(shù)的執(zhí)行,直到main結(jié)束
	defer func() {
		fmt.Println("Enter defer function")
		if p := recover(); p != nil {
			fmt.Printf("%v\n", p)
		}
		fmt.Println("Exit defer function")
	}()
	// 引發(fā)painc
	panic(errors.New("soming wrong"))
	fmt.Println("Exit function main")
}

五、多條defer語句多條defer語句的執(zhí)行順序

在同一個(gè)函數(shù)中,defer函數(shù)調(diào)用的執(zhí)行順序與它們分別所屬的defer語句的出現(xiàn)順序(更嚴(yán)謹(jǐn)?shù)卣f,是執(zhí)行順序)完全相反。

當(dāng)一個(gè)函數(shù)即將結(jié)束執(zhí)行時(shí),其中的寫在最下邊的defer函數(shù)調(diào)用會(huì)最先執(zhí)行,其次是寫在它上邊、與它的距離最近的那個(gè)defer函數(shù)調(diào)用,以此類推,最上邊的defer函數(shù)調(diào)用會(huì)最后一個(gè)執(zhí)行。

defer語句執(zhí)行的內(nèi)幕:

在defer語句每次執(zhí)行的時(shí)候,Go 語言會(huì)把它攜帶的defer函數(shù)及其參數(shù)值另行存儲(chǔ)到一個(gè)鏈表中。

這個(gè)鏈表與該defer語句所屬的函數(shù)是對(duì)應(yīng)的,并且,它是先進(jìn)后出(FILO)的,相當(dāng)于一個(gè)棧。

在需要執(zhí)行某個(gè)函數(shù)中的defer函數(shù)調(diào)用的時(shí)候,Go 語言會(huì)先拿到對(duì)應(yīng)的鏈表,然后從該鏈表中一個(gè)一個(gè)地取出defer函數(shù)及其參數(shù)值,并逐個(gè)執(zhí)行調(diào)用。

package main
import "fmt"
func main() {
	defer fmt.Println("first defer")
	for i := 0; i < 3; i++ {
		defer fmt.Printf("defer in for %d\n", i)
	}
	defer fmt.Println("last defer")
}

到此這篇關(guān)于GoLang中panic與recover函數(shù)以及defer語句超詳細(xì)講解的文章就介紹到這了,更多相關(guān)Go panic recover defer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang協(xié)程池gopool設(shè)計(jì)與實(shí)現(xiàn)

    Golang協(xié)程池gopool設(shè)計(jì)與實(shí)現(xiàn)

    本文主要介紹了Golang協(xié)程池gopool設(shè)計(jì)與實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Go?interface{}?轉(zhuǎn)切片類型的實(shí)現(xiàn)方法

    Go?interface{}?轉(zhuǎn)切片類型的實(shí)現(xiàn)方法

    本文主要介紹了Go?interface{}?轉(zhuǎn)切片類型的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Golang?中的?unsafe.Pointer?和?uintptr詳解

    Golang?中的?unsafe.Pointer?和?uintptr詳解

    這篇文章主要介紹了Golang中的unsafe.Pointer和uintptr詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • Golang結(jié)構(gòu)化日志包log/slog的使用詳解

    Golang結(jié)構(gòu)化日志包log/slog的使用詳解

    官方提供的用于打印日志的包是標(biāo)準(zhǔn)庫中的 log 包,該包雖然被廣泛使用,但是缺點(diǎn)也很多,所以Go 1.21新增的 log/slog 完美解決了以上問題,下面我們就來看看log/slog包的使用吧
    2023-09-09
  • go語言實(shí)現(xiàn)字符串與其它類型轉(zhuǎn)換(strconv包)

    go語言實(shí)現(xiàn)字符串與其它類型轉(zhuǎn)換(strconv包)

    strconv包是Go語言標(biāo)準(zhǔn)庫的一部分,主要提供字符串與基本數(shù)據(jù)類型之間的轉(zhuǎn)換功能,使用strconv包可以方便地在不同類型之間進(jìn)行轉(zhuǎn)換,滿足日常編程中的需求,感興趣的可以了解一下
    2024-10-10
  • gtoken替換jwt實(shí)現(xiàn)sso登錄的問題小結(jié)

    gtoken替換jwt實(shí)現(xiàn)sso登錄的問題小結(jié)

    這篇文章主要介紹了gtoken替換jwt實(shí)現(xiàn)sso登錄,主要介紹了替換jwt的原因分析及gtoken的優(yōu)勢(shì),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 淺析go逆向符號(hào)恢復(fù)

    淺析go逆向符號(hào)恢復(fù)

    這篇文章主要介紹了go逆向符號(hào)恢復(fù)的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 解決golang處理http response碰到的問題和需要注意的點(diǎn)

    解決golang處理http response碰到的問題和需要注意的點(diǎn)

    這篇文章主要介紹了解決golang處理http response碰到的問題和需要注意的點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 基于HLS創(chuàng)建Golang視頻流服務(wù)器的優(yōu)缺點(diǎn)

    基于HLS創(chuàng)建Golang視頻流服務(wù)器的優(yōu)缺點(diǎn)

    HLS 是 HTTP Live Streaming 的縮寫,是蘋果開發(fā)的一種基于 HTTP 的自適應(yīng)比特率流媒體傳輸協(xié)議。這篇文章主要介紹了基于 HLS 創(chuàng)建 Golang 視頻流服務(wù)器,需要的朋友可以參考下
    2021-08-08
  • Go語言實(shí)現(xiàn)漢諾塔算法

    Go語言實(shí)現(xiàn)漢諾塔算法

    之前的文章,我們給大家分享了不少漢諾塔算法的實(shí)現(xiàn)語言,包括C、c++、java、python等,今天我們就來使用go語言來實(shí)現(xiàn)一下,需要的小伙伴來參考下吧。
    2015-03-03

最新評(píng)論