最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang異常處理之defer,panic,recover的使用詳解

 更新時(shí)間:2022年05月28日 14:44:26   作者:中億豐數(shù)字科技有限公司  
這篇文章主要為大家介紹了Go語(yǔ)言異常處理機(jī)制中defer、panic和recover三者的使用方法,文中示例代碼講解詳細(xì),需要的朋友可以參考下

延遲是什么

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

defer可以延遲函數(shù)、延遲?法、延遲參數(shù)。

延遲函數(shù)

可以在函數(shù)中添加多個(gè)defer語(yǔ)句。

當(dāng)函數(shù)執(zhí)?到最后時(shí),這些defer語(yǔ)句會(huì)按照逆序執(zhí)?,最后該函數(shù)返回。特別是當(dāng)你在進(jìn)??些打開(kāi)資源的操作時(shí),遇到錯(cuò)誤需要提前返回,在返回前你需要關(guān)閉

相應(yīng)的資源,不然很容易造成資源泄露等問(wèn)題

如果有很多調(diào)?defer,那么defer是采?后進(jìn)先出模式

在離開(kāi)所在的?法時(shí),執(zhí)?(報(bào)錯(cuò)的時(shí)候也會(huì)執(zhí)?)

示例代碼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()。。") }

運(yùn)?結(jié)果:

我是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("結(jié)束!") }
func largest(s []int) {
 defer finished()
 fmt.Println("開(kāi)始尋找最?數(shù)...")
 max := s[0]
 for _, v := range s {
 if v > max {
 max = v
 }
 }
 fmt.Printf("%v中的最?數(shù)為:%v \n", s , max) }

運(yùn)?結(jié)果:

開(kāi)始尋找最?數(shù)…
[78 109 2 563 300]中的最?數(shù)為:563
結(jié)束!

延遲?法

延遲并不僅僅局限于函數(shù)。延遲?個(gè)?法調(diào)?也是完全合法的。

示例代碼:

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 ") }

運(yùn)?結(jié)果:

Welcome Steven Wang

延遲參數(shù)

延遲函數(shù)的參數(shù)在執(zhí)?延遲語(yǔ)句時(shí)被執(zhí)?,?不是在執(zhí)?實(shí)際的函數(shù)調(diào)?時(shí)執(zhí)?。

示例代碼:

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

運(yùn)?結(jié)果:

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

堆棧的推遲

當(dāng)?個(gè)函數(shù)有多個(gè)延遲調(diào)?時(shí),它們被添加到?個(gè)堆棧中,并在Last In First Out(LIFO)后進(jìn)先出的順序中執(zhí)?。

示例代碼:利?defer實(shí)現(xiàn)字符串倒序

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

返回結(jié)果:

原始字符串: StevenWang歡迎學(xué)習(xí)區(qū)塊鏈
翻轉(zhuǎn)后字符串:
鏈塊區(qū)習(xí)學(xué)迎歡gnaWnevetS

延遲的應(yīng)?

到?前為?,我們所寫(xiě)的示例代碼,并沒(méi)有實(shí)際的應(yīng)??,F(xiàn)在看?下關(guān)于延遲的應(yīng)?。在不考慮代碼流的情況下,延遲被執(zhí)?。讓我們以?個(gè)使?WaitGroup的程序示例來(lái)理解這個(gè)問(wèn)題。我們將?先編寫(xiě)程序?不使?延遲,然后我們將修改它以使?延遲,并理解延遲是多么有?。

示例代碼:

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")
}

程序運(yùn)?結(jié)果:

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(宕機(jī)和宕機(jī)恢復(fù))

panic和recover機(jī)制

1.概述:

panic:詞義"恐慌",recover:“恢復(fù)”

Go語(yǔ)?追求簡(jiǎn)潔優(yōu)雅,Go沒(méi)有像Java那樣的 try…catch…finally 異常處理機(jī)制。Go語(yǔ)?設(shè)計(jì)者認(rèn)為,將異常與流程控制混在?起會(huì)讓代碼變得混亂。

Go語(yǔ)?中,使?多值返回來(lái)返回錯(cuò)誤。不?異常代替錯(cuò)誤,更不?異常來(lái)控制流程。

go語(yǔ)?利?panic(),recover(),實(shí)現(xiàn)程序中的極特殊的異常處理。換句話說(shuō),極個(gè)別的情況下,Go才使?defer、panic、recover這種異常處理形式。

  • panic(),讓當(dāng)前的程序進(jìn)?恐慌,中斷程序的執(zhí)??;蛘哒f(shuō),panic是?個(gè)內(nèi)建函數(shù),可以中斷原有的控制流程,進(jìn)??個(gè)令?恐慌的流程中。
  • 當(dāng)函數(shù)F調(diào)?panic,函數(shù)F的執(zhí)?被中斷,但是F中的延遲函數(shù)會(huì)正常執(zhí)?,然后F返回到調(diào)?它的地?。在調(diào)?的地?,F(xiàn)的?為就像調(diào)?了panic。這?過(guò)程繼續(xù)向上,直到發(fā)?panic的goroutine中所有調(diào)?的函數(shù)返回,此時(shí)程序退出。
  • 恐慌可以直接調(diào)?panic產(chǎn)?。也可以由運(yùn)?時(shí)錯(cuò)誤產(chǎn)?,例如訪問(wèn)越界的數(shù)組。
  • recover 是?個(gè)內(nèi)建的函數(shù),可以讓進(jìn)?令?恐慌的流程中的goroutine恢復(fù)過(guò)來(lái)。
  • recover(),讓程序恢復(fù),必須在defer函數(shù)中執(zhí)?。換句話說(shuō),recover僅在延遲函數(shù)中有效。
  • 在正常 的執(zhí)?過(guò)程中,調(diào)?recover會(huì)返回nil,并且沒(méi)有其它任何效果。如果當(dāng)前的goroutine陷?恐慌,調(diào)? recover可以捕獲到panic的輸?值,并且恢復(fù)正常的執(zhí)?。

?定要記住,應(yīng)當(dāng)把它作為最后的?段來(lái)使?,也就是說(shuō),我們的代碼中應(yīng)當(dāng)沒(méi)有,或者很少有panic這樣的東?。

示例代碼

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

以上就是Golang異常處理之defer,panic,recover的使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Golang defer panic recover的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語(yǔ)言中接口組合的實(shí)現(xiàn)方法

    Go語(yǔ)言中接口組合的實(shí)現(xiàn)方法

    這篇文章主要介紹了Go語(yǔ)言中接口組合的實(shí)現(xiàn)方法,實(shí)例分析了接口中包含接口的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-02-02
  • golang時(shí)間處理工具箱now的使用詳解

    golang時(shí)間處理工具箱now的使用詳解

    這篇文章主要介紹了golang時(shí)間處理工具箱now的使用詳解,幫助大家更好的理解和學(xué)習(xí)使用golang,感興趣的朋友可以了解下
    2021-02-02
  • gorm update傳入struct對(duì)象,零值字段不更新的解決方案

    gorm update傳入struct對(duì)象,零值字段不更新的解決方案

    這篇文章主要介紹了gorm update傳入struct對(duì)象,零值字段不更新的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Go設(shè)計(jì)模式之迭代器模式講解和代碼示例

    Go設(shè)計(jì)模式之迭代器模式講解和代碼示例

    迭代器是一種行為設(shè)計(jì)模式, 讓你能在不暴露復(fù)雜數(shù)據(jù)結(jié)構(gòu)內(nèi)部細(xì)節(jié)的情況下遍歷其中所有的元素,本文將為大家詳細(xì)介紹Go 迭代器模式,文中詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-07-07
  • 從并發(fā)到并行解析Go語(yǔ)言中的sync.WaitGroup

    從并發(fā)到并行解析Go語(yǔ)言中的sync.WaitGroup

    Go?語(yǔ)言提供了許多工具和機(jī)制來(lái)實(shí)現(xiàn)并發(fā)編程,其中之一就是?sync.WaitGroup。本文就來(lái)深入討論?sync.WaitGroup,探索其工作原理和在實(shí)際應(yīng)用中的使用方法吧
    2023-05-05
  • Go語(yǔ)言編程中字符串切割方法小結(jié)

    Go語(yǔ)言編程中字符串切割方法小結(jié)

    這篇文章主要介紹了Go語(yǔ)言編程中字符串切割方法小結(jié),所整理的方法都來(lái)自字符串相關(guān)的strings包,需要的朋友可以參考下
    2015-10-10
  • Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Otto是一個(gè)用Go語(yǔ)言實(shí)現(xiàn)的JavaScript解釋器,可用于執(zhí)行和操作JavaScript代碼,適合在Go項(xiàng)目中執(zhí)行簡(jiǎn)單的JS腳本,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • Go語(yǔ)言開(kāi)發(fā)保證并發(fā)安全實(shí)例詳解

    Go語(yǔ)言開(kāi)發(fā)保證并發(fā)安全實(shí)例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言開(kāi)發(fā)保證并發(fā)安全實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • go語(yǔ)言channel實(shí)現(xiàn)多核并行化運(yùn)行的方法

    go語(yǔ)言channel實(shí)現(xiàn)多核并行化運(yùn)行的方法

    這篇文章主要介紹了go語(yǔ)言channel實(shí)現(xiàn)多核并行化運(yùn)行的方法,實(shí)例分析了channel實(shí)現(xiàn)多核并行化運(yùn)行的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • graphql---go http請(qǐng)求使用詳解

    graphql---go http請(qǐng)求使用詳解

    這篇文章主要介紹了graphql---go http請(qǐng)求使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12

最新評(píng)論

小金县| 芜湖市| 新乐市| 民勤县| 磐石市| 广宁县| 娄烦县| 赫章县| 阳朔县| 济源市| 盈江县| 任丘市| 延寿县| 南木林县| 察哈| 泾川县| 工布江达县| 英山县| 镇坪县| 宜兰县| 嘉义县| 囊谦县| 湘阴县| 拜城县| 桦川县| 茂名市| 襄樊市| 牡丹江市| 休宁县| 灵宝市| 垣曲县| 贺州市| 蒲江县| 荃湾区| 大连市| 剑阁县| 同德县| 交口县| 营口市| 县级市| 安远县|