GO基礎之延時執行


一、延遲是什么?
•即延遲( defer)語句,延遲語句被用於執行一個函數調用,在這個函數之前,延遲語句返回。


一、延遲函數

1、可以在函數中添加多個defer語句。
•當函數執行到最后時,這些defer■語句會按照逆序執行,最后該函數返回。特別是當你在進行一些打開資源的操作時,遇到錯誤需要提前返回,在返回前你需要關閉相應的資源,不然很容易造成資源泄露等問題
•如果有很多調用defer,那么defer是采用后進先出模式
•在離幵所在的方法時,執行(報錯的時候也會執行)

package main

import "fmt"
import (
    "base"
)
func main() {
    defer funcA()
    funcB()
    defer funcC()
    fmt.Println("main over...")
}

func funcA() {
    fmt.Println("這是funcA")
}

func funcB() {
    fmt.Println("這是funcB")
}

func funcC() {
    fmt.Println("這是funcC")
}
View Code

延遲方法(defe的數據結構類似於棧)

package main

import "fmt"

type person struct {
    firstName, lastName string
}

func (p person) fullName() {
    fmt.Printf("%s %s", p.firstName, p.lastName)
}

func main() {
    p := person{"Steven" , "Wang"}
    defer p.fullName()
    fmt.Print("Welcome ")
}
View Code

帶參數的defer函數

package main

import "fmt"

func main() {
    a := 5
    b := 6
    defer printAdd(a, b, true)
    a = 10
    b = 7
    printAdd(a, b, false)
}

func printAdd(a, b int, flag bool) {
    if flag {
        fmt.Printf("延遲執行函數printAdd() ,參數a,b分別為%d, %d , 兩數之和為:%d\n", a, b, a+b)
    } else {
        fmt.Printf("未延遲執行函數printAdd() ,參數a,b分別為%d, %d , 兩數之和為:%d\n", a, b, a+b)
    }
}
View Code

二、宕機panic和宕機恢復recover


(―)、panic和recover機制
1、概述:
• panic:詞義__恐慌recover:"恢復_■
• Go沒有像Java那樣的異常機制,它不能拋出異常,而是使用了 panic和recover機制。一定要記住,應當把它作為最后的手段來使用,也就是說,我們的代碼中應當沒有,或者很少有panic這樣的東西。
• go語言利用panicO, recover(),實現程序中的極特殊的異常處理
〇 panicO,讓當前的程序進入恐慌,中斷程序的執行
〇 recoverO,讓程序恢復,必須在defer函數中執行
〇 Panics—個內建函數,可以中斷原有的控制流程,進入一個令人恐慌的流程中。
〇當函數 F調用panic,函數 F的執行被中斷,但是F中的延遲函數會正常執行,然后F返回到調用它的地方。在調用的地方,F的行為就像調用了panic。這一過程繼續向上,直到發生panic的goroutine中所有調用的函數返回,此時程序退出。
〇恐慌可以直接調用panic產生。也可以由運行時錯誤產生,例如訪問越界的數組。
〇 Recover是一個內建的函數,可以讓進入令人恐慌的流程中的goroutine恢復過來。
〇 recover僅在延遲函數中有效。在正常的執行過程中,調用recover會返回nil,並且沒有其它任何效果。如果當前的goroutine陷入恐慌,調用recover•可以捕獲到panic的輸入值,並且恢復正常的執行

 

package main

import "fmt"

func main() {
    funcA()
    funcB()
    funcC()
    fmt.Println("main over")
}

func funcA() {
    fmt.Println("這是funcA")
}

func funcB() {
    defer func() {
        if msg := recover(); msg != nil {
            fmt.Println("恢復啦,獲取recover的返回值:", msg)
        }

    }()
    fmt.Println("這是funcB")
    for i := 0; i < 10; i++ {
        fmt.Println("i:", i)
        if i == 5 {
            //panic("funcB恐慌啦")
        }
    }
}

func funcC() {
    defer func() {
        fmt.Println("執行延遲函數")
        msg := recover()
        fmt.Println("獲取recover的返回值:", msg)
    }()
    fmt.Println("這是funcC")
    panic("funcC恐慌了")
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM