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

Golang中錯(cuò)誤處理機(jī)制詳解

 更新時(shí)間:2024年05月06日 09:51:04   作者:2021dragon  
平時(shí)在項(xiàng)目開(kāi)發(fā)過(guò)程中少不了對(duì)錯(cuò)誤的處理,一個(gè)好用的系統(tǒng)首先要確保其健壯性,不能經(jīng)常發(fā)生錯(cuò)誤就卡死之類的情況,為了讓我們的程序更加健壯,我們就需要知道golang里的錯(cuò)誤處理機(jī)制是怎么樣的,這篇文章帶大家一起學(xué)習(xí),需要的朋友跟著小編一起來(lái)看看吧

Golang錯(cuò)誤處理機(jī)制

panic異常

panic異常

  • Go的類型系統(tǒng)會(huì)在編譯時(shí)捕獲很多錯(cuò)誤,但有些錯(cuò)誤只能在運(yùn)行時(shí)檢查,比如除零錯(cuò)誤、數(shù)組訪問(wèn)越界、空指針引用等,這些運(yùn)行時(shí)錯(cuò)誤會(huì)引起panic異常。
  • 當(dāng)panic異常發(fā)生時(shí),程序會(huì)中斷運(yùn)行,并立即執(zhí)行當(dāng)前函數(shù)中的defer語(yǔ)句,然后程序會(huì)從調(diào)用棧中逐級(jí)返回,返回同時(shí)執(zhí)行各級(jí)函數(shù)中的defer語(yǔ)句,直到panic被捕獲或程序終止。

例如,下面的代碼在運(yùn)行過(guò)程中,由于存在除零錯(cuò)誤將導(dǎo)致panic異常。如下:

package main

import "fmt"

func Division(num1 int, num2 int) int {
	defer fmt.Println("Division defer...")
	return num1 / num2
}

func main() {
	defer fmt.Println("main defer...")
	// panic異常
	result := Division(10, 0)
	fmt.Printf("result = %d\n", result)
	fmt.Println("other code...")
}

運(yùn)行代碼后可以看到,main函數(shù)中調(diào)用Division函數(shù)之后的代碼沒(méi)有被執(zhí)行。但在程序退出之前,Division和main函數(shù)中的defer語(yǔ)句被逐一執(zhí)行。如下:

在這里插入圖片描述

recover捕獲異常

recover捕獲異常

  • 當(dāng)觸發(fā)panic異常時(shí),我們希望程序可以繼續(xù)運(yùn)行,并希望在觸發(fā)異常后,能夠執(zhí)行某些操作,比如給管理員發(fā)送一條告警信息。
  • 在Go中,捕獲異常通過(guò)在defer中調(diào)用內(nèi)建函數(shù)recover實(shí)現(xiàn),recover函數(shù)會(huì)使程序從panic中恢復(fù),并返回觸發(fā)panic的值,如果程序沒(méi)有發(fā)生panic,則recover調(diào)用將會(huì)返回nil。
  • 需要注意的是,當(dāng)異常被捕獲后,觸發(fā)panic異常的函數(shù)也不會(huì)繼續(xù)運(yùn)行,但能正常返回。

例如,下面在Division函數(shù)的defer中捕獲了panic異常,并將觸發(fā)panic異常的值進(jìn)行了返回。如下:

package main

import "fmt"

func Division(num1 int, num2 int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = r.(error) // 類型斷言,將r轉(zhuǎn)換為error類型(后續(xù)介紹)
		}
	}()
	return num1 / num2, nil
}

func main() {
	// recover捕獲異常
	result, err := Division(10, 0)
	if err != nil {
		fmt.Printf("division operation error, err = %v\n", err)
	} else {
		fmt.Printf("result = %d\n", result)
	}
}

運(yùn)行代碼后可以看到,由于panic異常被捕獲使得Division函數(shù)正常返回,同時(shí)main函數(shù)后續(xù)的代碼也被正常執(zhí)行。如下:

在這里插入圖片描述

由于panic異常會(huì)逐級(jí)拋出,直到異常被捕獲或程序終止,因此可以選擇在調(diào)用鏈的任意一個(gè)函數(shù)中對(duì)panic進(jìn)行捕獲。如下:

package main

import "fmt"

func Division(num1 int, num2 int) int {
	return num1 / num2
}

func main() {
	// recover捕獲異常
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("recoverd from panic, err = %v\n", err)
		}
	}()
	result := Division(10, 0)
	fmt.Printf("result = %d\n", result)
	fmt.Println("other code...")
}

由于Division函數(shù)中沒(méi)有對(duì)panic進(jìn)行捕獲,導(dǎo)致main函數(shù)觸發(fā)panic異常,雖然在main函數(shù)中對(duì)panic進(jìn)行了捕獲,但main函數(shù)的后續(xù)代碼將不會(huì)被執(zhí)行。如下:

在這里插入圖片描述

自定義錯(cuò)誤

自定義錯(cuò)誤

  • 不是只有程序在運(yùn)行時(shí)出現(xiàn)錯(cuò)誤才能觸發(fā)panic異常,通過(guò)調(diào)用內(nèi)建函數(shù)panic也能觸發(fā)panic異常。
  • panic函數(shù)能夠接收任何類型的值作為參數(shù),并在觸發(fā)panic時(shí)將其作為觸發(fā)panic的值。
  • 觸發(fā)panic的值通常是error類型的,通過(guò)errors包中的New函數(shù)可以創(chuàng)建一個(gè)error類型的錯(cuò)誤值,該函數(shù)接收一個(gè)string類型的參數(shù),并返回創(chuàng)建的error類型的錯(cuò)誤值。

例如,我們規(guī)定除數(shù)不能為20,否則觸發(fā)panic異常。如下:

package main

import (
	"errors"
	"fmt"
)

func Division(num1 int, num2 int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = r.(error)
		}
	}()
	if num2 == 20 {
		panic(errors.New("integer divide by 20"))
	}
	return num1 / num2, nil
}

func main() {
	// recover捕獲異常
	result, err := Division(10, 20)
	if err != nil {
		fmt.Printf("division operation error, err = %v\n", err)
	} else {
		fmt.Printf("result = %d\n", result)
	}
}

運(yùn)行代碼后可以看到,通過(guò)panic函數(shù)觸發(fā)的異常也能夠成功被捕獲。如下:

在這里插入圖片描述

說(shuō)明一下: 通過(guò)recover將panic捕獲后,可以繼續(xù)通過(guò)調(diào)用panic函數(shù)將panic再次拋出,使其傳播到更高層的調(diào)用棧進(jìn)行進(jìn)一步處理,這叫做異常的重新拋出。

到此這篇關(guān)于Golang中錯(cuò)誤處理機(jī)制詳解的文章就介紹到這了,更多相關(guān)Golang錯(cuò)誤處理機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang函數(shù)這些神操作你知道哪些

    Golang函數(shù)這些神操作你知道哪些

    這篇文章主要為大家介紹了一些Golang中函數(shù)的神操作,不知道你都知道哪些呢?文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下
    2023-02-02
  • go-micro微服務(wù)JWT跨域認(rèn)證問(wèn)題

    go-micro微服務(wù)JWT跨域認(rèn)證問(wèn)題

    JWT 以 JSON 對(duì)象的形式安全傳遞信息。因?yàn)榇嬖跀?shù)字簽名,因此所傳遞的信息是安全的,這篇文章主要介紹了go-micro微服務(wù)JWT跨域認(rèn)證,需要的朋友可以參考下
    2023-01-01
  • Go語(yǔ)言怎么使用變長(zhǎng)參數(shù)函數(shù)

    Go語(yǔ)言怎么使用變長(zhǎng)參數(shù)函數(shù)

    本文主要介紹了Go語(yǔ)言怎么使用變長(zhǎng)參數(shù)函數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 深入解析golang?bufio

    深入解析golang?bufio

    這篇文章主要介紹了golang?bufio解析,golang的bufio庫(kù)使用緩存來(lái)一次性進(jìn)行大塊數(shù)據(jù)的讀寫(xiě),以此降低IO系統(tǒng)調(diào)用,提升性能,需要的朋友可以參考下
    2022-04-04
  • Go語(yǔ)言實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)簡(jiǎn)單分布式系統(tǒng)

    Go語(yǔ)言實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)簡(jiǎn)單分布式系統(tǒng)

    如今很多云原生系統(tǒng)、分布式系統(tǒng),例如?Kubernetes,都是用?Go?語(yǔ)言寫(xiě)的,這是因?yàn)?Go?語(yǔ)言天然支持異步編程。本篇文章將介紹如何用?Go?語(yǔ)言編寫(xiě)一個(gè)簡(jiǎn)單的分布式系統(tǒng),需要的小伙伴開(kāi)業(yè)跟隨小編一起學(xué)習(xí)一下
    2022-10-10
  • Golang在Mac、Linux、Windows下如何交叉編譯的實(shí)現(xiàn)

    Golang在Mac、Linux、Windows下如何交叉編譯的實(shí)現(xiàn)

    這篇文章主要介紹了Golang在Mac、Linux、Windows下如何交叉編譯的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 數(shù)據(jù)競(jìng)爭(zhēng)和內(nèi)存重分配Golang slice并發(fā)不安全問(wèn)題解決

    數(shù)據(jù)競(jìng)爭(zhēng)和內(nèi)存重分配Golang slice并發(fā)不安全問(wèn)題解決

    這篇文章主要為大家介紹了數(shù)據(jù)競(jìng)爭(zhēng)和內(nèi)存重分配Golang slice并發(fā)不安全問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 深入探討Go語(yǔ)言中的預(yù)防性接口為什么是不必要的

    深入探討Go語(yǔ)言中的預(yù)防性接口為什么是不必要的

    在Go語(yǔ)言中,有一種從其他語(yǔ)言帶來(lái)的常見(jiàn)模式:預(yù)防性接口,雖然這種模式在?Java?等語(yǔ)言中很有價(jià)值,但在Go中往往會(huì)成為反模式,本文我們就來(lái)深入探討一下原因
    2025-01-01
  • go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法和原理解析

    go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法和原理解析

    這篇文章主要介紹了go-micro使用Consul做服務(wù)發(fā)現(xiàn)的方法和原理,這里提供一個(gè)通過(guò)docker快速安裝Consul的方式,當(dāng)然前提是你得安裝了docker,需要的朋友可以參考下
    2022-04-04
  • 在Golang中執(zhí)行Shell命令的教程詳解

    在Golang中執(zhí)行Shell命令的教程詳解

    在本教程中,我們將學(xué)習(xí)如何在 Golang 中執(zhí)行shell命令(如 ls、mkdir 或 grep ),我們還將學(xué)習(xí)如何通過(guò) stdin 和 stdout 傳遞 I/O 到正在運(yùn)行的命令,以及管理長(zhǎng)時(shí)間運(yùn)行的命令,感興趣的同學(xué)可以借鑒一下
    2023-05-05

最新評(píng)論