亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

go?defer避坑指南之拆解延遲語句

 更新時間:2023年11月16日 11:22:30   作者:王中陽Go  
這篇文章主要為大家詳細介紹了go?defer避坑指南之如何拆解延遲語句,掌握正確使用方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

對齊基本概念

Go語言的延遲語句defer有哪些特點?通常在什么情況下使用?

Go語言的延遲語句(defer statement)具有以下特點:

  • 延遲執(zhí)行:延遲語句會在包含它的函數(shù)執(zhí)行結束前執(zhí)行,無論函數(shù)是正常返回還是發(fā)生異常。
  • 后進先出:如果有多個延遲語句,它們會按照后進先出(LIFO)的順序執(zhí)行。也就是說,最后一個延遲語句會最先執(zhí)行,而第一個延遲語句會最后執(zhí)行。

通常情況下,延遲語句在以下情況下使用:

  • 資源釋放:延遲語句可以用于在函數(shù)返回前釋放打開的文件、關閉數(shù)據庫連接、釋放鎖等資源,以確保資源的正確釋放,避免資源泄漏。
  • 錯誤處理:延遲語句可以用于處理函數(shù)執(zhí)行過程中可能發(fā)生的錯誤。通過在函數(shù)開始時設置延遲語句,在函數(shù)返回前檢查錯誤并進行相應的處理,可以簡化錯誤處理的邏輯。
  • 日志記錄:延遲語句可以用于在函數(shù)返回前記錄日志或執(zhí)行其他的調試操作,以便在函數(shù)執(zhí)行過程中收集相關的信息。

延遲語句的使用可以提高代碼的可讀性和可維護性,同時確保資源的釋放和清理操作按照逆序進行。它是Go語言中一種常用的編程技巧,用于處理資源管理和錯誤處理等場景。

避坑之旅

實際開發(fā)中defer的使用并不像前面介紹的這么簡單,defer用不好,會陷入泥潭。

下面我從兩個角度帶大家避坑:

  • 首先拆解一下延遲語句的執(zhí)行,注意Go語言的return語句不是原子性的;
  • 另外重點和大家分享一下defer語句后面接匿名函數(shù)和非匿名函數(shù)的區(qū)別。

拆解延遲語句

避免陷入泥潭的關鍵是必須深刻理解下面這條語句:

return xxx

上面這條語句經過編譯之后,實際上生成了三條指令:

1)返回值 =xxx。

2)調用 defer 函數(shù)。

3)空的 return。

第1和第 3 步是return語句生成的指令,也就是說return并不是一條原子指令;

第2步是 defer 定義的語句,這里可能會操作返回值,從而影響最終結果。

下面來看兩個例子,試著將return 語句和 defer語句拆解到正確的順序。

第一個例子

func f()(r int){
  t:=5

  defer func(){
    t=t+5
    }()
    
  return t
}

拆解后:

func f()(r int){
  t:=5
  
  //1,賦值指令
  r=t

  // 2.defer 被插入到斌值與返回之間執(zhí)行,這個例子中返回值r沒被修改過 
  func(){
    t=t+5
    }()
    
  //3.空的 return 指令
  return
  }

這里第二步實際上并沒有操作返回值r,因此,main函數(shù)中調用f()得到5。

第二個例子

func f()(r int){
  defer func(r int){
    r=r+5
    }(r)
    
    return 1
}

拆解后:

func f() (r int) {
  //1.賦值 
  r=1
  
  //2.這里改的r是之前傳進去的r,不會改變要返回的那個r值 
  func(r int) {
    r=r+5
  }(r)
  
  // 3. 空的 return 
  return
}

第二步,改變的是傳值進去的r,是形參的一個復制值,不會影響實參r。因此,main函數(shù)中需要調用f()得到1。

defer匿名函數(shù)

在Go語言中,使用匿名函數(shù)作為defer的參數(shù)時,可以理解為:defer語句中的匿名函數(shù)在包裹該defer語句的函數(shù)返回后才執(zhí)行。這是因為defer語句的執(zhí)行時機是在包裹函數(shù)即將返回之前,但在實際返回之前。

為什么不是在return語句之前執(zhí)行呢?這是因為defer語句的設計初衷是為了在函數(shù)返回之前執(zhí)行一些清理操作,例如關閉文件、釋放資源等。將defer語句放在return語句之后,可以確保在函數(shù)返回之前執(zhí)行這些清理操作,保證函數(shù)的執(zhí)行完整性和資源的正確釋放。

在使用匿名函數(shù)和非匿名函數(shù)作為defer的參數(shù)時,主要區(qū)別在于對函數(shù)參數(shù)的傳遞和作用域的影響:

  • 匿名函數(shù)作為defer的參數(shù):匿名函數(shù)可以直接在defer語句中定義,可以訪問外部函數(shù)的變量,并且在執(zhí)行時會使用當前的變量值。這種方式可以方便地在defer語句中使用外部變量,但需要注意變量的值在執(zhí)行時可能已經發(fā)生了改變。
  • 非匿名函數(shù)作為defer的參數(shù):非匿名函數(shù)需要先定義好,然后作為defer的參數(shù)傳遞。在執(zhí)行時,會使用函數(shù)的當前參數(shù)值。這種方式可以在defer語句中使用已定義的函數(shù),但需要注意函數(shù)參數(shù)的傳遞和作用域。

產生這種區(qū)別的原因是,匿名函數(shù)和非匿名函數(shù)在定義和作用域上的差異。匿名函數(shù)可以直接在defer語句中定義,可以訪問外部函數(shù)的變量,而非匿名函數(shù)需要先定義好,然后作為參數(shù)傳遞。這種設計靈活性使得開發(fā)者可以根據具體的需求選擇合適的方式來使用defer語句。

舉例來說

當使用匿名函數(shù)作為defer的參數(shù)時,可以在defer語句中直接定義匿名函數(shù),并訪問外部變量。

以下是一個示例代碼:

package main

import "fmt"

func main() {
    x := 10

    defer func() {
        fmt.Println("Deferred anonymous function:", x)
    }()

    x = 20
    fmt.Println("Before return:", x)
}

在上述示例中,匿名函數(shù)作為defer的參數(shù),可以訪問外部變量x。 在函數(shù)返回之前,defer語句中的匿名函數(shù)會執(zhí)行,并打印出x的值。

輸出結果如下:

當使用非匿名函數(shù)作為defer的參數(shù)時,需要先定義好函數(shù),然后將函數(shù)名作為defer的參數(shù)傳遞。

以下是一個示例代碼:

package main

import "fmt"

func main() {
    x := 10

    defer printX(x)

    x = 20
    fmt.Println("Before return:", x)
}

func printX(x int) {
    fmt.Println("Deferred function:", x)
}

在上述示例中,printX函數(shù)作為defer的參數(shù)傳遞,函數(shù)定義在main函數(shù)之后。

在函數(shù)返回之前,defer語句中的printX函數(shù)會執(zhí)行,并打印出傳遞的參數(shù)x的值。輸出結果如下:

總結一下

通過以上示例,我們可以明確體現(xiàn)出使用匿名函數(shù)和非匿名函數(shù)作為defer的參數(shù)的區(qū)別。

匿名函數(shù)可以直接在defer語句中定義,并訪問外部變量,而非匿名函數(shù)需要先定義好函數(shù),然后將函數(shù)名作為參數(shù)傳遞。

通過前面帶著大家拆解了defer的語句的執(zhí)行,相信大家可以更好的理解了。

到此這篇關于go defer避坑指南之拆解延遲語句的文章就介紹到這了,更多相關go defer內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • golang sql語句超時控制方案及原理

    golang sql語句超時控制方案及原理

    一般應用程序在執(zhí)行一條sql語句時,都會給這條sql設置一個超時時間,本文主要介紹了golang sql語句超時控制方案及原理,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • go select編譯期的優(yōu)化處理邏輯使用場景分析

    go select編譯期的優(yōu)化處理邏輯使用場景分析

    select 是 Go 中的一個控制結構,類似于用于通信的 switch 語句。每個 case 必須是一個通信操作,要么是發(fā)送要么是接收。接下來通過本文給大家介紹go select編譯期的優(yōu)化處理邏輯使用場景分析,感興趣的朋友一起看看吧
    2021-06-06
  • golang的空標識符理解

    golang的空標識符理解

    今天小編就為大家分享一篇關于golang的空標識符理解,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • 詳解Golang中的通道機制與應用

    詳解Golang中的通道機制與應用

    這篇文章主要來和大家一起深入探討了Go語言中通道(Channel)的各個方面,文章詳細解析了通道的類型、操作方法以及垃圾回收機制,有需要的可以了解下
    2023-10-10
  • go-zero源碼閱讀之布隆過濾器實現(xiàn)代碼

    go-zero源碼閱讀之布隆過濾器實現(xiàn)代碼

    布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優(yōu)點是空間效率和查詢時間都比一般的算法要好的多,缺點是有一定的誤識別率和刪除困難,這篇文章主要介紹了go-zero源碼閱讀-布隆過濾器,需要的朋友可以參考下
    2023-02-02
  • Golang 經典校驗庫 validator 用法解析

    Golang 經典校驗庫 validator 用法解析

    這篇文章主要為大家介紹了Golang 經典校驗庫 validator 用法解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 淺析Go語言中的方法集合與選擇receiver類型

    淺析Go語言中的方法集合與選擇receiver類型

    這篇文章主要為大家詳細介紹了Go語言中的方法集合與選擇receiver類型的相關知識,文中的示例代碼講解詳細,對我們深入學習go語言有一定的幫助,需要的可以參考下
    2023-11-11
  • Go語言中的定時器原理與實戰(zhàn)應用

    Go語言中的定時器原理與實戰(zhàn)應用

    在Go語言中,Timer和Ticker是處理定時任務的重要工具,Timer用于一次性事件,而Ticker則用于周期性事件,本文詳細介紹了這兩種定時器的創(chuàng)建、使用和停止方法,并通過實際案例展示了它們在監(jiān)控日志、檢查系統(tǒng)狀態(tài)等方面的應用
    2024-10-10
  • Go語言編程通過dwarf獲取內聯(lián)函數(shù)

    Go語言編程通過dwarf獲取內聯(lián)函數(shù)

    這篇文章主要為大家介紹了Go語言編程通過dwarf獲取內聯(lián)函數(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Golang 定時器(Timer 和 Ticker),這篇文章就夠了

    Golang 定時器(Timer 和 Ticker),這篇文章就夠了

    這篇文章主要介紹了Golang 定時器(Timer 和 Ticker),這篇文章就夠了,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10

最新評論