成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

解密defer語句:避免踩坑,掌握延遲執(zhí)行的正確姿勢

開發(fā) 前端
通過以上示例,我們可以明確體現(xiàn)出使用匿名函數(shù)和非匿名函數(shù)作為defer的參數(shù)的區(qū)別。匿名函數(shù)可以直接在defer語句中定義,并訪問外部變量,而非匿名函數(shù)需要先定義好函數(shù),然后將函數(shù)名作為參數(shù)傳遞。


基本概念

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

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

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

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

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

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

避坑之旅

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

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

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

拆解延遲語句

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

return xxx

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

1)返回值 =xxx。

2)調(diào)用 defer 函數(shù)。

3)空的 return。

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

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

下面來看兩個例子,試著將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ù)中調(diào)用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是之前傳進(jìn)去的r,不會改變要返回的那個r值 
  func(r int) {
    r=r+5
  }(r)
  
  // 3. 空的 return 
  return
}

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

圖片圖片


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

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

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

舉例來說

當(dāng)使用匿名函數(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的值。

輸出結(jié)果如下:

圖片圖片

當(dāng)使用非匿名函數(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的值。輸出結(jié)果如下:

圖片圖片

總結(jié)一下

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

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

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

本文轉(zhuǎn)載自微信公眾號「 程序員升級打怪之旅」,作者「  王中陽Go」,可以通過以下二維碼關(guān)注。

轉(zhuǎn)載本文請聯(lián)系「 程序員升級打怪之旅」公眾號。

責(zé)任編輯:武曉燕 來源: 程序員升職加薪之旅
相關(guān)推薦

2021-07-05 07:55:11

PC端移動端設(shè)計

2021-06-09 08:21:14

Webpack環(huán)境變量前端

2021-04-02 09:50:14

微服務(wù)分布式鎖Java

2022-04-19 11:48:54

開發(fā)npm踩坑

2025-04-10 08:21:17

2020-12-22 09:34:20

JavaScript開發(fā)技術(shù)

2020-08-10 06:47:31

CSSTRouBLe前端

2024-04-30 10:59:03

WebSocketCSS選擇器

2018-01-11 15:31:39

命令Linux關(guān)機

2017-02-23 15:37:44

OptionObject容器

2016-05-09 10:41:03

算法分析開發(fā)

2021-07-28 07:22:40

SQL順序Hive

2017-03-16 11:39:33

Openstack源碼姿勢

2023-01-30 07:41:43

2017-07-10 13:09:45

前端Flexbox

2023-02-20 08:11:04

2023-06-01 07:37:48

級別事務(wù)調(diào)度

2017-10-12 11:30:34

Spark代碼PR

2021-01-08 08:10:34

MySQL表空間回收

2016-12-12 08:48:24

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产午夜精品一区二区三区嫩草 | 青青草社区 | av在线免费观看不卡 | 国产视频一区二区 | 国产激情在线播放 | 久久99久久 | 日本三级电影在线看 | 成人免费视频观看 | 在线观看 亚洲 | 欧美性网站 | 久久亚洲国产精品 | 国产精品7777777 | 黄色视频a级毛片 | 久久精品中文字幕 | 中文字幕高清 | 国产精品毛片av一区 | 浮生影院免费观看中文版 | 中文字幕日韩欧美 | 国产精品久久久久久久白浊 | 午夜影院在线观看视频 | 国产一级片在线播放 | 国产91网址 | 区一区二在线观看 | 国产aⅴ爽av久久久久久久 | 欧美久久视频 | 亚洲精品乱码久久久久久9色 | 97成人在线 | 手机av免费在线 | 国产亚洲精品久久午夜玫瑰园 | 国内自拍第一页 | 我我色综合 | 欧产日产国产精品国产 | 国产人久久人人人人爽 | 国产在线视频一区 | 蜜桃精品视频在线 | 欧美精品福利视频 | 天天操伊人 | 国产91在线播放 | 99久久婷婷国产综合精品电影 | 国产亚洲成av人片在线观看桃 | 国产一区二区激情视频 |