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

golang之資源釋放/異常錯(cuò)誤處理解析

 更新時(shí)間:2024年01月07日 09:00:22   作者:后廠村村長  
這篇文章主要為大家介紹了golang之資源釋放/異常錯(cuò)誤處理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

資源釋放-defer

類似于其他語言的 析構(gòu)函數(shù) 比如PHP的 __destruct

func b() error {
    resp, err := http.Get("xxx.com")
    // 先判斷操作是否成功
    if err != nil {
        return err
    }
    // 如果操作成功,再進(jìn)行Close操作
    defer resp.Body.Close()
    return nil
}

從上面的示例可看到,defer 是個(gè)延遲函數(shù)(延遲執(zhí)行)

關(guān)于 defer 的一些常見誤區(qū)和陷阱

defer 語句是用來延遲執(zhí)行函數(shù)的,且延遲發(fā)生在函數(shù) return 之后具體指: Go return 在底層等于: 返回值入棧, defer函數(shù)調(diào)用, return

func returnValues() int {
    var result int
    defer func() {
        // defer 匿名函數(shù)對變量的修改發(fā)生在 return 之后
        result++
        fmt.Println("defer")
    }()
    return result
}
// 如下輸出 0
fmt.Println(returnValues())

go允許多個(gè)defer同時(shí)存在

defer 執(zhí)行順序遵循先進(jìn)后出 first-in-last-out (FILO)屬于棧操作,如下輸出:3、2、1

func stackingDefers() { 
    defer func() {
        fmt.Println("1")
    }()
    defer func() {
        fmt.Println("2")
    }()
    defer func() {
        fmt.Println("3")
    }()
}

函數(shù)被 deferred 時(shí)涉及的 參數(shù)變量值 在 defer 函數(shù)編寫時(shí)確定,而非實(shí)際調(diào)用時(shí)

func c() {
    i := 0
    defer fmt.Println(i) // 此時(shí)i變量值已被確定,即0
    i++
    defer fmt.Println(i) // 此時(shí)i++已執(zhí)行,變量值已被確定為 1
}
// 輸出 1 0;因?yàn)閐efer的執(zhí)行順序?yàn)?后進(jìn)先出,所以先輸出 i++ 之后的 1;再輸出之前的 0

defer與閉包陷阱

先來看一個(gè)示例:

func main() {
    i := 1
    defer func() {
        fmt.Println("defer-閉包i值:", i)
    }()
    defer fmt.Println("defer-i值:", i)
    i += 100
}

結(jié)果輸出為:

defer-i值: 1
defer-閉包i值: 101

為啥捏?

  • 第二個(gè)defer,因?yàn)楹瘮?shù)被 deferred 時(shí)涉及的 參數(shù)變量值 在 defer 函數(shù)編寫時(shí)已確定,所以輸出 defer-i值: 1
  • 第一個(gè)defer,閉包中的參數(shù)傳遞是引用類型傳遞,因此匿名函數(shù)中的 i 可以輸出 101(匿名函數(shù)都是閉包,按引用類型傳遞)

try-catch-finally

Go追求簡潔優(yōu)雅,所以不支持傳統(tǒng)的 try-catch-finally 結(jié)構(gòu),因?yàn)镚o語言的設(shè)計(jì)者們認(rèn)為,將異常與控制結(jié)構(gòu)混在一起很容易使得代碼變混亂(咱不懂,但內(nèi)心大受震撼)。

如果要在go實(shí)現(xiàn)這么個(gè)邏輯,需要用到這么幾個(gè)關(guān)鍵詞:defer, panic, recover如何使用 defer 執(zhí)行 try-catch-finally 調(diào)試:

func main() {
    // 類似其他語言的 try (隱式包含)
    defer func() {
        // 捕獲異常:類似 catch(\Exception $e)
        if err := recover(); err != nil {
            // 輸出異常
            fmt.Println(err)
            // 打印錯(cuò)誤堆棧: 類似于PHP的 debug_print_backtrace
            debug.PrintStack() // 輸出到日志即可
            fmt.Println()
            fmt.Println("執(zhí)行:planB!")
            planB()
        }
    }()
    // 注意??!用recover處理panic指令,defer 須在 panic 之前聲明,否則panic時(shí)會(huì)直接退出,recover無法捕獲到panic
    tryCatchFinally()
    fmt.Println("dadada...") // 這里不會(huì)執(zhí)行
}
func tryCatchFinally() {
    fmt.Println("begin")
    panic("拋出異常信息: throw new exception")
    fmt.Println("end") // 這里不會(huì)執(zhí)行
}
func planB() {
    fmt.Println("exec-planB, done!!")
}

關(guān)于內(nèi)建函數(shù) recover

1、用來控制一個(gè) goroutine 的 panicking 行為,捕獲panic,從而影響應(yīng)用的行為
2、一般調(diào)用方式

  • 在defer函數(shù)中,通過 recover 來終止一個(gè) gojroutine 的 panicking 過程,從而恢復(fù)正常邏輯的執(zhí)行
  • 獲取通過panic傳遞的error,執(zhí)行捕獲之后的邏輯,參考傳統(tǒng)tryCatchFinally

EOF - 錯(cuò)誤處理

另一種常見錯(cuò)誤處理,即 EOF(End-Of-File)文件結(jié)尾錯(cuò)誤,可以直接捕獲,示例如下:

reader := strings.NewReader("clear is better than clever")
p := make([]byte, 5)
for {
    n, err := reader.Read(p)
    if err != nil {
        if err == io.EOF {
            fmt.Println("EOF:", n)
        } else {
            fmt.Println(err)
        }
        os.Exit(1)
    }
    // 注: p 每次循環(huán)都會(huì)被覆蓋,但如果最后一行不足5個(gè)字節(jié)時(shí):
    // 僅會(huì)覆蓋最后一行獲取到的相應(yīng)的字節(jié)數(shù),比如最后一行3字節(jié),僅覆蓋p的前3個(gè),第4、5個(gè)字節(jié)維持上次循環(huán)時(shí)的賦值
    // 所以這里輸出時(shí)使用了:p[:n]
    fmt.Println(n, string(p[:n]))
}

如上執(zhí)行結(jié)果:

5 clear
5  is b
5 etter
5  than
5  clev
2 erlev
EOF: 0
exit status 1

以上就是golang之資源釋放/異常錯(cuò)誤處理解析的詳細(xì)內(nèi)容,更多關(guān)于golang資源釋放異常錯(cuò)誤處理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺析Go 字符串指紋

    淺析Go 字符串指紋

    這篇文章主要介紹了Go 字符串指紋的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)go語言,感興趣的朋友可以了解下
    2020-09-09
  • 獲取Golang環(huán)境變量的三種方式小結(jié)

    獲取Golang環(huán)境變量的三種方式小結(jié)

    本文介紹了Golang中獲取環(huán)境變量的三種方式,包含使用Viper包、GoDotEnv包和os包,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • Golang使用gin框架實(shí)現(xiàn)一個(gè)完整的聊天室功能

    Golang使用gin框架實(shí)現(xiàn)一個(gè)完整的聊天室功能

    由于我們項(xiàng)目的需要,我就研究了一下關(guān)于websocket的相關(guān)內(nèi)容,去實(shí)現(xiàn)一個(gè)聊天室的功能,經(jīng)過幾天的探索,現(xiàn)在使用Gin框架實(shí)現(xiàn)了一個(gè)完整的聊天室+消息實(shí)時(shí)通知系統(tǒng),感興趣的小伙伴歡迎閱讀本文
    2023-08-08
  • golang通過node_exporter監(jiān)控GPU及cpu頻率、溫度的代碼

    golang通過node_exporter監(jiān)控GPU及cpu頻率、溫度的代碼

    node_exporter這個(gè)開源組件是配合prometheus收集主機(jī)操作系統(tǒng)層的metrics的常用組件,但是官方?jīng)]有提供GPU卡的metrics的采集,今天通過本文給大家介紹golang通過node_exporter監(jiān)控GPU及cpu頻率、溫度的相關(guān)知識,感興趣的朋友一起看看吧
    2022-05-05
  • Golang中Map按照Value大小排序的方法實(shí)例

    Golang中Map按照Value大小排序的方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于Golang中Map按照Value大小排序的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Go語言獲取系統(tǒng)性能數(shù)據(jù)gopsutil庫的操作

    Go語言獲取系統(tǒng)性能數(shù)據(jù)gopsutil庫的操作

    這篇文章主要介紹了Go語言獲取系統(tǒng)性能數(shù)據(jù)gopsutil庫的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang實(shí)現(xiàn)自己的Redis(TCP篇)實(shí)例探究

    Golang實(shí)現(xiàn)自己的Redis(TCP篇)實(shí)例探究

    這篇文章主要介紹了Golang實(shí)現(xiàn)自己的Redis(TCP篇)實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go語言Gin處理響應(yīng)方式詳解

    Go語言Gin處理響應(yīng)方式詳解

    gin框架封裝了常用的數(shù)據(jù)格式方法響應(yīng)于客戶端,下面這篇文章主要給大家介紹了關(guān)于Go語言Gin處理響應(yīng)方式的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • golang grpc 負(fù)載均衡的方法

    golang grpc 負(fù)載均衡的方法

    這篇文章主要介紹了golang grpc 負(fù)載均衡的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • Golang?Template實(shí)現(xiàn)自定義函數(shù)的操作指南

    Golang?Template實(shí)現(xiàn)自定義函數(shù)的操作指南

    這篇文章主要為大家詳細(xì)介紹了Golang如何利用Template實(shí)現(xiàn)自定義函數(shù)的操作,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02

最新評論