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

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

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

一、運行時恐慌panic

panic是一種在運行時拋出來的異常。比如"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: "右邊的內容,正是panic包含的runtime.Error類型值的字符串表示形式;

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

這里的ID編號并不重要,是GO語言運行時系統(tǒng)內部給予的一個goroutine編號,我們在程序中無法獲取,也無法改變。

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

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

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

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

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

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

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

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

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

打印錯誤信息:

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

四、施加應對panic的保護措施從而避免程序崩潰

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

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

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

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

package main
import (
	"errors"
	"fmt"
)
func main() {
	fmt.Println("Enter function main")
	// 延遲func函數(shù)的執(zhí)行,直到main結束
	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í)行順序

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

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

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

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

這個鏈表與該defer語句所屬的函數(shù)是對應的,并且,它是先進后出(FILO)的,相當于一個棧。

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

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")
}

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

相關文章

  • Go語言中常見的坑以及高性能編程技巧分享

    Go語言中常見的坑以及高性能編程技巧分享

    代碼的穩(wěn)健性、高性能、可讀性是我們每一位coder必須去追求的目標,本文結合Go語言的特性做了相關總結,感興趣的小伙伴可以了解一下
    2023-06-06
  • Go并發(fā)之RWMutex的源碼解析詳解

    Go并發(fā)之RWMutex的源碼解析詳解

    RWMutex是一個支持并行讀串行寫的讀寫鎖。RWMutex具有寫操作優(yōu)先的特點,寫操作發(fā)生時,僅允許正在執(zhí)行的讀操作執(zhí)行,后續(xù)的讀操作都會被阻塞。本文就來從源碼解析一下RWMutex的使用
    2023-03-03
  • Go語言中內存管理逃逸分析詳解

    Go語言中內存管理逃逸分析詳解

    所謂的逃逸分析(Escape?analysis)是指由編譯器決定內存分配的位置嗎不需要程序員指定。本文就來和大家簡單分析一下Go語言中內存管理逃逸吧
    2023-03-03
  • Go語言普通指針unsafe.Pointer?uintpt之間的關系及指針運算

    Go語言普通指針unsafe.Pointer?uintpt之間的關系及指針運算

    這篇文章主要為大家介紹了Go語言普通指針unsafe.Pointer?uintpt之間的關系及指針運算示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 深入理解go unsafe用法及注意事項

    深入理解go unsafe用法及注意事項

    go雖然是一種高級語言,但是也還是給開發(fā)者提供了指針的類型unsafe.Pointer,我們可以通過它來直接讀寫變量的內存,本文來了解一下?unsafe?里所能提供的關于指針的一些功能,以及使用unsafe.Pointer的一些注意事項
    2024-01-01
  • go?zero微服務實戰(zhàn)處理每秒上萬次的下單請求

    go?zero微服務實戰(zhàn)處理每秒上萬次的下單請求

    這篇文章主要為大家介紹了go?zero微服務實戰(zhàn)處理每秒上萬次的下單請求示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • go?分布式鎖簡單實現(xiàn)實例詳解

    go?分布式鎖簡單實現(xiàn)實例詳解

    這篇文章主要為大家介紹了go?分布式鎖簡單實現(xiàn)實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • golang利用redis和gin實現(xiàn)保存登錄狀態(tài)校驗登錄功能

    golang利用redis和gin實現(xiàn)保存登錄狀態(tài)校驗登錄功能

    這篇文章主要介紹了golang利用redis和gin實現(xiàn)保存登錄狀態(tài)校驗登錄功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • Go語言中?Print?Printf和Println?的區(qū)別解析

    Go語言中?Print?Printf和Println?的區(qū)別解析

    這篇文章主要介紹了Go語言中?Print?Printf和Println?的區(qū)別,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • go-zero讀取請求體出現(xiàn)EOF錯誤的解決方法

    go-zero讀取請求體出現(xiàn)EOF錯誤的解決方法

    這篇文章主要為大家詳細介紹了go-zero讀取請求體出現(xiàn)EOF錯誤時如何解決,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-02-02

最新評論