首頁 > 後端開發 > Golang > 主體

golang如何防止意外崩潰

發布: 2020-03-27 14:44:22
原創
4031 人瀏覽過

golang如何防止意外崩潰

無論是程式碼​​運行錯誤由Runtime 層拋出的panic 崩潰,還是主動觸發的panic 崩潰,都可以配合defer 和recover 實現錯誤捕捉和恢復,讓程式碼在發生崩潰後允許繼續運行。

Go 沒有異常系統,其使用 panic 觸發宕機類似於其他語言的拋出異常,那麼 recover 的宕機恢復機制就對應 try/catch 機制。

讓程式在崩潰時繼續執行

下面的程式碼實作了ProtectRun() 函數,該函數傳入一個匿名函數或閉包後的執行函數,當傳入函數以任何形式發生panic 崩潰後,可以將崩潰發生的錯誤列印出來,同時允許後面的程式碼繼續運行,不會造成整個進程的崩潰。

保護運行函數:

package main
 
import (
"fmt"
"runtime"
)
 
// 崩溃时需要传递的上下文信息
type panicContext struct {
function string // 所在函数
}
 
// 保护方式允许一个函数
func ProtectRun(entry func()) {
 
// 延迟处理的函数
defer func() {
 
// 发生宕机时,获取panic传递的上下文并打印
err := recover()
 
switch err.(type) {
case runtime.Error: // 运行时错误
fmt.Println("runtime error:", err)
default: // 非运行时错误
fmt.Println("error:", err)
}
 
}()
 
entry()
 
}
 
func main() {
fmt.Println("运行前")
 
// 允许一段手动触发的错误
ProtectRun(func() {
 
fmt.Println("手动宕机前")
 
// 使用panic传递上下文
panic(&panicContext{
"手动触发panic",
})
 
fmt.Println("手动宕机后")
})
 
// 故意造成空指针访问错误
ProtectRun(func() {
 
fmt.Println("赋值宕机前")
 
var a *int
*a = 1
 
fmt.Println("赋值宕机后")
})
 
fmt.Println("运行后")
}
登入後複製

對程式碼的說明:

第 9 行宣告描述錯誤的結構體,成員保存錯誤的執行函數。

第 17 行使用 defer 將閉包延遲執行,當 panic 觸發崩潰時,ProtectRun() 函數將結束運行,此時 defer 後的閉包將會發生呼叫。

第 20 行,recover() 取得到 panic 傳入的參數。

第 22 行,使用 switch 對 err 變數進行型別斷言。

第 23 行,如果錯誤是有 Runtime 層拋出的運行時錯誤,如空指標存取、除數為 0 等情況,列印執行階段錯誤。

第 25 行,其他錯誤,列印傳遞過來的錯誤資料。

第 44 行,使用 panic 手動觸發一個錯誤,並將一個結構體附帶訊息傳遞過去,此時,recover 就會取得到這個結構體訊息,並列印出來。

第 57 行,模擬程式碼中空指標賦值造成的錯誤,此時會由 Runtime 層拋出錯誤,被 ProtectRun() 函數的 recover() 函數捕獲。

panic和recover的關係

panic 和 defer 的組合有以下特性:

有 panic 沒 recover,程式宕機。

有 panic 也有 recover 捕獲,程式不會宕機。執行完對應的 defer 後,從宕機點退出目前函數後繼續執行。

更多golang知識請關注PHP中文網golang教學欄位。

以上是golang如何防止意外崩潰的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板