中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang異常處理之defer,panic,recover如何使用

發布時間:2022-05-30 09:47:31 來源:億速云 閱讀:129 作者:iii 欄目:開發技術

今天小編給大家分享一下Golang異常處理之defer,panic,recover如何使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

延遲是什么

defer即延遲語句,極個別的情況下,Go才使?defer、panic、recover這種異常處理形式。

defer可以延遲函數、延遲?法、延遲參數。

延遲函數

可以在函數中添加多個defer語句。

當函數執?到最后時,這些defer語句會按照逆序執?,最后該函數返回。特別是當你在進??些打開資源的操作時,遇到錯誤需要提前返回,在返回前你需要關閉

相應的資源,不然很容易造成資源泄露等問題

如果有很多調?defer,那么defer是采?后進先出模式

在離開所在的?法時,執?(報錯的時候也會執?)

示例代碼1:

package main
import "fmt"
func main() {
 defer funA()
 funB()
 funC()
 fmt.Println("main...over....") }
func funA() {
 fmt.Println("我是funA()...") }
func funB() { //
 fmt.Println("我是funB()...") }
func funC() {
 fmt.Println("我是funC()。。") }

運?結果:

我是funB()...
我是funC()。。
main...over....
我是funA()...

示例代碼2:

package main
import "fmt"
func main() {
 s1 := []int{78, 109, 2, 563, 300}
 largest(s1) }
func finished() {
 fmt.Println("結束!") }
func largest(s []int) {
 defer finished()
 fmt.Println("開始尋找最?數...")
 max := s[0]
 for _, v := range s {
 if v > max {
 max = v
 }
 }
 fmt.Printf("%v中的最?數為:%v \n", s , max) }

運?結果:

開始尋找最?數…
[78 109 2 563 300]中的最?數為:563
結束!

延遲?法

延遲并不僅僅局限于函數。延遲?個?法調?也是完全合法的。

示例代碼:

package main
import "fmt"
type person struct {
 firstName string
 lastName string
}
func (p person) fullName() {
 fmt.Printf("%s %s", p.firstName, p.lastName) }
func main() {
 p := person{"Steven", "Wang"}
 defer p.fullName()
 fmt.Printf("Welcome ") }

運?結果:

Welcome Steven Wang

延遲參數

延遲函數的參數在執?延遲語句時被執?,?不是在執?實際的函數調?時執?。

示例代碼:

package main
import "fmt"
func printAdd(a , b int) {
 fmt.Printf("延遲函數中:參數a , b分別為%d,%d ,兩數之和為:%d\n",
a , b , a+b) }
func main() {
 a := 5
 b := 6
 //延遲函數的參數在執?延遲語句時被執?,?不是在執?實際的函數調
?時執?。
 defer printAdd(a , b)
 a = 10
 b = 7
 fmt.Printf("延遲函數執?前:參數a , b分別為%d,%d ,兩數之和為:
%d\n", a , b , a+b) }

運?結果:

延遲函數執?前:參數a , b分別為10,7 ,兩數之和為:17
延遲函數中:參數a , b分別為5,6 ,兩數之和為:11

堆棧的推遲

當?個函數有多個延遲調?時,它們被添加到?個堆棧中,并在Last In First Out(LIFO)后進先出的順序中執?。

示例代碼:利?defer實現字符串倒序

package main
import "fmt"
func main() {
 name := "StevenWang歡迎學習區塊鏈"
 fmt.Printf("原始字符串: %s\n", name)
 fmt.Println("翻轉后字符串: ")
 ReverseString(name) }
func ReverseString(str string) {
 for _, v := range []rune(str) {
 defer fmt.Printf("%c", v)
 }
}

返回結果:

原始字符串: StevenWang歡迎學習區塊鏈
翻轉后字符串:
鏈塊區習學迎歡gnaWnevetS

延遲的應?

到?前為?,我們所寫的示例代碼,并沒有實際的應?。現在看?下關于延遲的應?。在不考慮代碼流的情況下,延遲被執?。讓我們以?個使?WaitGroup的程序示例來理解這個問題。我們將?先編寫程序?不使?延遲,然后我們將修改它以使?延遲,并理解延遲是多么有?。

示例代碼:

package main
import (
 "fmt"
 "sync"
)
type rect struct {
 length int
 width int
}
func (r rect) area(wg *sync.WaitGroup) {
 if r.length < 0 {
 fmt.Printf("rect %v's length should be greater than zero\n", r)
 wg.Done()
 return
 }
 if r.width < 0 {
 fmt.Printf("rect %v's width should be greater than zero\n", r)
 wg.Done()
 return
 }
 area := r.length * r.width
 fmt.Printf("rect %v's area %d\n", r, area)
 wg.Done()
}
func main() {
 var wg sync.WaitGroup
 r1 := rect{-67, 89}
 r2 := rect{5, -67}
 r3 := rect{8, 9}
 rects := []rect{r1, r2, r3}
 for _, v := range rects {
 wg.Add(1)
 go v.area(&wg)
 }
 wg.Wait()
 fmt.Println("All go routines finished executing")
}

修改以上代碼:

package main
import (
 "fmt"
 "sync"
)
type rect struct {
 length int
 width int
}
func (r rect) area(wg *sync.WaitGroup) {
 defer wg.Done()
 if r.length < 0 {
 fmt.Printf("rect %v's length should be greater than zero\n", r)
 return
 }
 if r.width < 0 {
 fmt.Printf("rect %v's width should be greater than zero\n", r)
 return
 }
 area := r.length * r.width
 fmt.Printf("rect %v's area %d\n", r, area) }
func main() {
 var wg sync.WaitGroup
 r1 := rect{-67, 89}
 r2 := rect{5, -67}
 r3 := rect{8, 9}
 rects := []rect{r1, r2, r3}
 for _, v := range rects {
 wg.Add(1)
 go v.area(&wg)
 }
 wg.Wait()
 fmt.Println("All go routines finished executing")
}

程序運?結果:

rect {8 9}'s area 72
rect {-67 89}'s length should be greater than zero
rect {5 -67}'s width should be greater than zero
All go routines finished executing

panic和recover(宕機和宕機恢復)

panic和recover機制

1.概述:

panic:詞義"恐慌",recover:“恢復”

Go語?追求簡潔優雅,Go沒有像Java那樣的 try&hellip;catch&hellip;finally 異常處理機制。Go語?設計者認為,將異常與流程控制混在?起會讓代碼變得混亂。

Go語?中,使?多值返回來返回錯誤。不?異常代替錯誤,更不?異常來控制流程。

go語?利?panic(),recover(),實現程序中的極特殊的異常處理。換句話說,極個別的情況下,Go才使?defer、panic、recover這種異常處理形式。

  • panic(),讓當前的程序進?恐慌,中斷程序的執?。或者說,panic是?個內建函數,可以中斷原有的控制流程,進??個令?恐慌的流程中。

  • 當函數F調?panic,函數F的執?被中斷,但是F中的延遲函數會正常執?,然后F返回到調?它的地?。在調?的地?,F的?為就像調?了panic。這?過程繼續向上,直到發?panic的goroutine中所有調?的函數返回,此時程序退出。

  • 恐慌可以直接調?panic產?。也可以由運?時錯誤產?,例如訪問越界的數組。

  • recover 是?個內建的函數,可以讓進?令?恐慌的流程中的goroutine恢復過來。

  • recover(),讓程序恢復,必須在defer函數中執?。換句話說,recover僅在延遲函數中有效。

  • 在正常 的執?過程中,調?recover會返回nil,并且沒有其它任何效果。如果當前的goroutine陷?恐慌,調? recover可以捕獲到panic的輸?值,并且恢復正常的執?。

?定要記住,應當把它作為最后的?段來使?,也就是說,我們的代碼中應當沒有,或者很少有panic這樣的東?。

示例代碼

package main
import "fmt"
func main() {
 /*
 panic:詞義"恐慌",
 recover:"恢復"
 go語?利?panic(),recover(),實現程序中的極特殊的異常的處理
 panic(),讓當前的程序進?恐慌,中斷程序的執?
 recover(),讓程序恢復,必須在defer函數中執?
 */
 funA()
 funB()
 funC()
 fmt.Println("main...over....") }
func funA() {
 fmt.Println("我是函數funA()...") }
func funB() { //外圍函數
 defer func() {
 if msg := recover(); msg != nil {
 fmt.Println(msg, "恢復啦。。。")
 }
 }()
 fmt.Println("我是函數funB()...")
 for i := 1; i <= 10; i++ {
 fmt.Println("i:", i)
 if i == 5 {
 //讓程序中斷
 panic("funB函數,恐慌啦。。。") //打斷程序的執?。。
 }
 }
 //當外圍函數中的代碼引發運?恐慌時,只有其中所有的延遲函數都執?完畢后,該運
?時恐慌才會真正被擴展?調?函數。
}
func funC() {
 defer func() {
 fmt.Println("func的延遲函數。。。")
 //if msg := recover(); msg != nil {
 // fmt.Println(msg, "恢復啦。。。")
 //}
 fmt.Println("recover執?了" , recover())
 }()
 fmt.Println("我是函數funC()。。")
 panic("funC恐慌啦。。") }

以上就是“Golang異常處理之defer,panic,recover如何使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宁晋县| 泽普县| 高要市| 华容县| 资阳市| 吴川市| 淳安县| 文化| 当涂县| 佛坪县| 营口市| 阳山县| 宁波市| 安阳市| 仲巴县| 苗栗县| 霍山县| 无为县| 商河县| 甘孜县| 百色市| 镇安县| 洛隆县| 信宜市| 樟树市| 会同县| 东乡县| 咸阳市| 上高县| 武强县| 册亨县| 辽宁省| 蕉岭县| 台湾省| 桐柏县| 青铜峡市| 麻栗坡县| 丹江口市| 黑山县| 远安县| 南投县|