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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)GO教程:Go語言宕機(jī)(panic)——程序終止運(yùn)行

Go語言的類型系統(tǒng)會在編譯時捕獲很多錯誤,但有些錯誤只能在運(yùn)行時檢查,如數(shù)組訪問越界、空指針引用等,這些運(yùn)行時錯誤會引起宕機(jī)。

宕機(jī)不是一件很好的事情,可能造成體驗(yàn)停止、服務(wù)中斷,就像沒有人希望在取錢時遇到 ATM 機(jī)藍(lán)屏一樣,但是,如果在損失發(fā)生時,程序沒有因?yàn)殄礄C(jī)而停止,那么用戶將會付出更大的代價,這種代價可以是金錢、時間甚至生命,因此,宕機(jī)有時也是一種合理的止損方法。

一般而言,當(dāng)宕機(jī)發(fā)生時,程序會中斷運(yùn)行,并立即執(zhí)行在該 goroutine(可以先理解成線程)中被延遲的函數(shù)(defer 機(jī)制),隨后,程序崩潰并輸出日志信息,日志信息包括 panic value 和函數(shù)調(diào)用的堆棧跟蹤信息,panic value 通常是某種錯誤信息。

對于每個 goroutine,日志信息中都會有與之相對的,發(fā)生 panic 時的函數(shù)調(diào)用堆棧跟蹤信息,通常,我們不需要再次運(yùn)行程序去定位問題,日志信息已經(jīng)提供了足夠的診斷依據(jù),因此,在我們填寫問題報告時,一般會將宕機(jī)和日志信息一并記錄。

雖然Go語言的 panic 機(jī)制類似于其他語言的異常,但 panic 的適用場景有一些不同,由于 panic 會引起程序的崩潰,因此 panic 一般用于嚴(yán)重錯誤,如程序內(nèi)部的邏輯不一致。任何崩潰都表明了我們的代碼中可能存在漏洞,所以對于大部分漏洞,我們應(yīng)該使用Go語言提供的錯誤機(jī)制,而不是 panic。

手動觸發(fā)宕機(jī)

Go語言可以在程序中手動觸發(fā)宕機(jī),讓程序崩潰,這樣開發(fā)者可以及時地發(fā)現(xiàn)錯誤,同時減少可能的損失。

Go語言程序在宕機(jī)時,會將堆棧和 goroutine 信息輸出到控制臺,所以宕機(jī)也可以方便地知曉發(fā)生錯誤的位置,那么我們要如何觸發(fā)宕機(jī)呢,示例代碼如下所示:

package main

func main() {
    panic("crash")
}

代碼運(yùn)行崩潰并輸出如下:

panic: crash

goroutine 1 [running]:
main.main()
    D:/code/main.go:4 +0x40
exit status 2

以上代碼中只用了一個內(nèi)建的函數(shù) panic() 就可以造成崩潰,panic() 的聲明如下:

func panic(v interface{})    //panic() 的參數(shù)可以是任意類型的。

在運(yùn)行依賴的必備資源缺失時主動觸發(fā)宕機(jī)

regexp 是Go語言的正則表達(dá)式包,正則表達(dá)式需要編譯后才能使用,而且編譯必須是成功的,表示正則表達(dá)式可用。

編譯正則表達(dá)式函數(shù)有兩種,具體如下:

1) func Compile(expr string) (*Regexp, error)

編譯正則表達(dá)式,發(fā)生錯誤時返回編譯錯誤同時返回 Regexp 為 nil,該函數(shù)適用于在編譯錯誤時獲得編譯錯誤進(jìn)行處理,同時繼續(xù)后續(xù)執(zhí)行的環(huán)境。

2) func MustCompile(str string) *Regexp

當(dāng)編譯正則表達(dá)式發(fā)生錯誤時,使用 panic 觸發(fā)宕機(jī),該函數(shù)適用于直接使用正則表達(dá)式而無須處理正則表達(dá)式錯誤的情況。

MustCompile 的代碼如下:

func MustCompile(str string) *Regexp {
    regexp, error := Compile(str)
    if error != nil {
        panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
    }
    return regexp
}

代碼說明如下:

  • 第 1 行,編譯正則表達(dá)式函數(shù)入口,輸入包含正則表達(dá)式的字符串,返回正則表達(dá)式對象。
  • 第 2 行,Compile() 是編譯正則表達(dá)式的入口函數(shù),該函數(shù)返回編譯好的正則表達(dá)式對象和錯誤。
  • 第 3 和第 4 行判斷如果有錯,則使用 panic() 觸發(fā)宕機(jī)。
  • 第 6 行,沒有錯誤時返回正則表達(dá)式對象。

手動宕機(jī)進(jìn)行報錯的方式不是一種偷懶的方式,反而能迅速報錯,終止程序繼續(xù)運(yùn)行,防止更大的錯誤產(chǎn)生,不過,如果任何錯誤都使用宕機(jī)處理,也不是一種良好的設(shè)計習(xí)慣,因此應(yīng)根據(jù)需要來決定是否使用宕機(jī)進(jìn)行報錯。

在宕機(jī)時觸發(fā)延遲執(zhí)行語句

當(dāng) panic() 觸發(fā)的宕機(jī)發(fā)生時,panic() 后面的代碼將不會被運(yùn)行,但是在 panic() 函數(shù)前面已經(jīng)運(yùn)行過的 defer 語句依然會在宕機(jī)發(fā)生時發(fā)生作用,參考下面代碼:

package main

import "fmt"

func main() {
    defer fmt.Println("宕機(jī)后要做的事情1")
    defer fmt.Println("宕機(jī)后要做的事情2")
    panic("宕機(jī)")
}

代碼輸出如下:

宕機(jī)后要做的事情2
宕機(jī)后要做的事情1
panic: 宕機(jī)

goroutine 1 [running]:
main.main()
    D:/code/main.go:8 +0xf8
exit status 2

對代碼的說明:

  • 第 6 行和第 7 行使用 defer 語句延遲了 2 個語句。
  • 第 8 行發(fā)生宕機(jī)。

宕機(jī)前,defer 語句會被優(yōu)先執(zhí)行,由于第 7 行的 defer 后執(zhí)行,因此會在宕機(jī)前,這個 defer 會優(yōu)先處理,隨后才是第 6 行的 defer 對應(yīng)的語句,這個特性可以用來在宕機(jī)發(fā)生前進(jìn)行宕機(jī)信息處理。


標(biāo)題名稱:創(chuàng)新互聯(lián)GO教程:Go語言宕機(jī)(panic)——程序終止運(yùn)行
網(wǎng)站地址:http://www.5511xx.com/article/dhscddp.html