Golang 中的 panic 與 recover 理解
Golang 有2個內建的函式 panic() 和 recover(),用以報告和捕獲執行時發生的程式錯誤,與 error 不同,panic-recover 一般用在函式內部。一定要注意不要濫用 panic-recover,可能會導致效能問題。
使用panic丟擲異常,丟擲異常後將立即停止當前函式的執行並執行所有被defer的函式,然後將panic拋向上一層,直至程式carsh。但是也可以使用被defer的recover函式來捕獲異常阻止程式的崩潰,recover只有被defer後才是有意義的。
必須注意:
1. defer 需要放在 panic 之前定義,另外recover只有在 defer 呼叫的函式中才有效。
2. recover處理異常後,邏輯並不會恢復到 panic 那個點去,函式跑到 defer 之後的那個點.
3. 多個 defer 會形成 defer 棧,後定義的 defer 語句會被最先呼叫
panic (主動爆出異常) 與 recover (收集異常)
recover 用來對panic的異常進行捕獲. panic 用於向上傳遞異常,執行順序是在 defer 之後。
下面舉個含有異常的例子:
func f() {
for {
fmt.Println("1")
a := []string{"a","b"}
fmt.Println(a[3]) // 這裡slice越界異常了
/*panic("bug")*/
fmt.Println("4")
time.Sleep(1 * time .Second)
}
}
如果不把這個異常panic recover處理的化,那麼就會發生下面的情況.
1
panic: runtime error: index out of range
goroutine 1 [running]:
panic(0xda9c0, 0x8201c8090)
/usr/local/go/src/runtime/panic.go:464 +0x3e6
main.f()
/Users/dxy/gg.go:23 +0x33b
main.main()
/Users/dxy/gg.go:16 +0x14
exit status 2
下面是處理panic的例子.
import (
"fmt"
"time"
)
func main() {
defer func() { //必須要先宣告defer,否則不能捕獲到panic異常
fmt.Println("2")
if err := recover(); err != nil {
fmt.Println(err) //這裡的err其實就是panic傳入的內容,bug
}
fmt.Println("3")
}()
f()
}
func f() {
for {
fmt.Println("1")
panic("bug")
fmt.Println("4") //不會執行的.
time.Sleep(1 * time.Second)
}
}
那麼上面程式碼的執行結果是:
1
2
bug
3
上面go程式碼例項中,異常是我們通過panic方法主動丟擲來的,但如果真的就出現了未知的異常咋辦?
package main
import (
"fmt"
"time"
)
func main() {
f()
fmt.Println("end")
}
func f() {
defer func() { //必須要先宣告defer,否則不能捕獲到panic異常
fmt.Println("netdxy.cn start")
if err := recover(); err != nil {
fmt.Println(err) //這裡的err其實就是panic傳入的內容,"bug"
}
fmt.Println("netdxy.cn end")
}()
for {
fmt.Println("1")
a := []string{"a", "b"}
fmt.Println(a[3]) // 越界訪問,肯定出現異常
panic("bug”) // 上面已經出現異常了,所以肯定走不到這裡了。
fmt.Println("4") //不會執行的.
time.Sleep(1 * time.Second)
}
}
我們可以看到出現的異常會走到defer這一步,defer這裡可以列印具體的異常資訊,defer執行完之後不能回到原點,控制權會被扔到該函式的外層,也就是呼叫這個函式的層,對應上面的程式碼也就是main()函式。
上面go程式碼執行結果是:
1
netdxy.cn start
runtime error: index out of range
netdxy.cn end
end
相關推薦
Golang 中的 panic 與 recover 理解
Golang 有2個內建的函式 panic() 和 recover(),用以報告和捕獲執行時發生的程式錯誤,與 error 不同,panic-recover 一般用在函式內部。一定要注意不要濫用 panic-recover,可能會導致效能問題。 使用panic
GO_05_2:Golang 中 panic、recover、defer 的用法
log logs lan finall 可能 錯誤處理 錯誤 異常處理 auto 函數 defer 1. 它的執行方式類似其他語言中的折構函數,在函數體執行結束後按照調用順序的 相反順序 逐個執行 2. 即使函數發生 嚴重錯誤 也會被執行,類似於 java 中 t
Golang中Struct與DB中表字段通過反射自動映射 - sqlmapper
size http 維護 default arc struct 自動 地址 字符 Golang中操作數據庫已經有現成的庫"database/sql"可以用,但是"database/sql"只提供了最基礎的操作接口; 對數據庫中一張表的增刪改查等操作,必須手動編寫sql st
mybatis中的${}與#{}的理解
破壞 字段名 數據 from 兩種 opera 使用場景 any operator mybatis作為目前java較為常使用的orm框架,其中動態sql的參數的註入有${}與#{兩種形式,下面來介紹一下他們之間的區別, #{}作為參數註入的方式時,從表象上來看,是在
Golang中make與new
轉自:https://www.cnblogs.com/junneyang/p/6070238.html make、new操作 make用於內建型別(map、slice 和channel)的記憶體分配。new用於各種型別的記憶體分配。 內建函式new本質上說跟其
golang中json與struct中tag
使用 Golang 的 encoding/json 庫已經提供了很好的封裝,可以讓我們很方便地進行 JSON 資料的轉換。 Go 語言中資料結構和 JSON 型別的對應關係如下表: golang 型別 JSON 型別 注意事項 bool JSO
go panic與recover分析及錯誤處理
先介紹一下什麼叫error 型別 error 是一種型別,表示錯誤狀態的型別,如果沒有錯誤則是nil。直白點將:error 型別就是描述錯誤的一種型別。 panic 在golang goroutine 的作用 panic 官方文件介紹:
golang中json與struct中tag簡介
使用 Golang 的 encoding/json 庫已經提供了很好的封裝,可以讓我們很方便地進行 JSON 資料的轉換。 Go 語言中資料結構和 JSON 型別的對應關係如下表: golang 型別 JSON 型別 注意事項 bool JSON boolean
Golang中位運算的理解於應用場景
pan golang ike xor 需要 常用 一個 amp 符號 一:位運算的介紹 百度百科的介紹,大家作為一個參考說明 https://baike.baidu.com/item/%E4%BD%8D%E8%BF%90%E7%AE%97/6888804?fr=al
golang中Array與Slice
range make imp 形參 隱式 amp [] 報錯 同時 在golang中有數組和Slice兩種數據結構,Slice是基於數組的實現,是長度動態不固定的數據結構,本質上是一個對數組字序列的引用,提供了對數組的輕量級訪問。那麽在go的函數中以數組或Slice為形參的
Golang中的panic和recover
func panic(interface{})和func recover() interface{}是Golang中用於錯誤處理的兩個函式。 panic的作用就是丟擲一條錯誤資訊,從它的引數型別可以看到它可以丟擲任意型別的錯誤資訊。在函式執行過程中的某處呼叫了panic,則立即丟擲一個錯誤資訊,同時
golang中recover和panic用法
golang中沒有try... catch...,所以當golang中遇到panic時,如果不進行recover,便會導致整個程式掛掉,具體例子如下: package main import ( "fmt" ) func main() { panic("fault
99%的人都理解錯了HTTP中GET與POST的區別
tex method 無限 ext 一點 size 環境 ans 交通 GET和POST是HTTP請求的兩種基本方法,要說它們的區別,接觸過WEB開發的人都能說出一二。 最直觀的區別就是GET把參數包含在URL中,POST通過request body傳遞參數。
【轉】C#中Func與Action的理解
.net ring UNC 簡單 代碼 操作 不必要 返回值 tps 原文地址:https://www.cnblogs.com/ultimateWorld/p/5608122.html Action 與 Func是.NET類庫中增加的內置委托,以便更加簡潔方便的使用委托。最
JavaScript在頁面中的執行順序(理解聲明式函數與賦值式函數) 轉載
AD TE 我們 行動 first FN 順序 而且 編譯性語言 JavaScript在頁面中的執行順序 https://blog.csdn.net/superhoy/article/details/52946277 2016年10月27日 15:38:52 閱讀數:
自己對golang中各個文件的理解
mode bsp 關於 信息 outer model option 其他 都是 models -》 裏面寫關於數據庫方面數據controllers -》邏輯,請求方法等conf -》註冊數據庫信息routers -》初始化路由線路views -》測試界面 實際
Yii2.0中Yii::$app與Yii 1.0中Yii:app()的理解
框架源碼 靜態 UNC 一個 eap eba 你在 this 模式 一直不明白Yii::$app與Yii::app(),查找yii框架源碼後如下記錄分享 (1)在Yii1.0中Yii::app()返回的是你在index.php裏創建的CWebApplication實例,在對
99%的人可能都理解錯了HTTP中GET與POST的區別
角色 ref 裏的 們的 接受 遺憾 為什麽 eth ges GET和POST是HTTP請求的兩種基本方法,要說它們的區別,接觸過WEB開發的人都能說出一二。 最直觀的區別就是GET把參數包含在URL中,POST通過request body傳遞參數。 你可能自己寫過無數個G
Golang 中如何用 CGO 與 C 之間做一個快取 buffer
Golang 是一個不錯的語言,尤其是做一個快取中間層是非常非常容易的。比較常見的場景就是我們在讀一個很大很大的檔案的時候,我們是做不到一次載入檔案到記憶體的,Golang 可以做到一點一點的將檔案讀至末尾,慢慢處理完,相信很多語言也很容易做到這個,那如果在處理這個檔案的時候專案的主語言是 Golang 而需