亚洲综合原千岁中文字幕_国产精品99久久久久久久vr_无码人妻aⅴ一区二区三区浪潮_成人h动漫精品一区二区三

主頁 > 知識庫 > Golang之defer 延遲調用操作

Golang之defer 延遲調用操作

熱門標簽:仙桃400電話辦理 重慶慶云企業400電話到哪申請 上海極信防封電銷卡價格 寧波語音外呼系統公司 地圖標注免費定制店 宿遷便宜外呼系統代理商 湛江crm外呼系統排名 不封卡外呼系統 鄭州智能語音電銷機器人價格

前言

defer語句被用于預定對一個函數的調用。我們把這類被defer語句調用的函數稱為延遲函數。而defer 延遲語句在其他編程語言里好像沒有見到。應該是屬于 Go 語言里的獨有的關鍵字。但用法類似于面向對象編程語言 Java 和 C# 的 finally 語句塊。

下面對defer進行介紹。

defer特性

1. 關鍵字 defer 用于注冊延遲調用。

2. 這些調用直到 return 前才被執。因此,可以用來做資源清理。

3. 多個defer語句,按先進后出的方式執行。

1.延遲調用

用法很簡單,只需要在函數前面加上 defer就行,就能實現將這個 該函數的調用延遲到當前函數執行完后再執行。例如:

package main 
import (
 "fmt"
)
func myFunc(){
 fmt.Println("minger")
}
func main(){
 defer myFunc() //等價于defer fmt.Println("minger")
 fmt.Println("程序猿編碼")
}

編譯運行:

2.defer 與 return 孰先孰后

defer 和 return 到底是哪個先調用?先看看例子:

package main 
import (
 "fmt"
)
var name string = "go"
func myFunc() string {
  defer func() {
    name = "python"
  }()
  fmt.Println("myFunc 函數里的name:", name)
  return name
}
func main() {
  myName := myFunc()
  fmt.Println("main 函數里的name: ", name)
  fmt.Println("main 函數里的myname: ", myName )

編譯運行:

來看看打印信息,第一行輸出,name 此時還是全局變量,值還是go

第二行輸出,在 defer 里改變了全局變量,此時name的值已經變成了 python

重點在第三行,為什么輸出的是 go ?

解釋只有一個,那就是 defer 是return 后才調用的。所以在執行 defer 前,myName 已經被賦值成 go 了。

3.多個defer 逆序執行

還是老規矩先來上代碼,看看輸出信息,例子:

package main 
import (
 "fmt"
)
func main(){
 name := "go"
 defer fmt.Println(name)
 name = "C/C++"
 defer fmt.Println(name)
 name = "Python"
 fmt.Println(name)
}

編譯輸出:

可見 多個defer 是它們會以逆序執行(類似棧,即后進先出)。

defer官方的解釋

Each time a “defer” statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred. If a deferred function value evaluates to nil, execution panics when the function is invoked, not when the “defer” statement is executed.

翻譯一下:

每次defer語句執行的時候,會把函數“壓棧”,函數參數會被拷貝下來;當外層函數(非代碼塊,如一個for循環)退出時,defer函數按照定義的逆序執行;如果defer執行的函數為nil, 那么會在最終調用函數的產生panic.

為什么需要defer?

往往我們在編程的時候,經常需要打開一些資源,比如數據庫連接、文件、鎖等,這些資源需要在用完之后釋放掉,否則會造成內存泄漏。

因此我們有時會忘記關閉這些資源。Golang直接在語言層面提供defer關鍵字,在打開資源語句的下一行,就可以直接用defer語句來注冊函數結束后執行關閉資源的操作。

defer用途

1. 關閉文件句柄

2. 鎖資源釋放

3. 數據庫連接釋放

defer的使用其實非常簡單,來看看一個簡單用途:

package main
import (
 "log"
 "os"
)
func main() {
 f, err := os.OpenFile("text.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) //文件沒有就創建,文件存在就追加
 if err != nil {
 log.Fatal(err)
 }
 defer f.Close()
 f.WriteString("程序猿編碼\n")
}

編譯輸出:

在打開文件的語句附近,用defer語句關閉文件。這樣,在函數結束之前,會自動執行defer后面的語句來關閉文件。

當然,defer會有小小地延遲,對時間要求特別特別特別高的程序,可以避免使用它。

總結

defer 語句經常使用于成對的操作,比如打開和關閉,連接和斷開,加鎖和解鎖,即便是再復雜的控制流,資源在任何情況下都能夠正確釋放。

補充:Golang中defer的三個實戰要點

前言

Golang中的defer是使用頻次比較高的,能創造出延遲生效特效的一種方式。

defer也有自己的矯情,需要注意的。

本文將從通過代碼的方式來說明defer的三點矯情。

1.defer的生效順序

2.defer與return,函數返回值之間的順序

3.defer定義和執行兩個步驟,做的事情。

正文

1.defer的生效順序

先說結論:defer的執行順序是倒序執行(同入棧先進后出)

func main() {
 defer func() {
 fmt.Println("我后出來")
 }()
 defer func() {
 fmt.Println("我先出來")
 }()
}

執行后打印出:

我先出來

我后出來

2.defer與return,函數返回值之間的順序

先說結論:return最先執行->return負責將結果寫入返回值中->接著defer開始執行一些收尾工作->最后函數攜帶當前返回值退出

返回值的表達方式,我們知道根據是否提前聲明有兩種方式:一種是func test() int 另一種是 func test() (i int),所以兩種情況都來說說

func test() int
func main() {
 fmt.Println("main:", test())
}
func test() int {
 var i int
 defer func() {
 i++
 fmt.Println("defer2的值:", i)
 }()
 defer func() {
 i++
 fmt.Println("defer1的值:", i)
 }()
 return i
}

輸出:

defer1的值: 1

defer2的值: 2

main: 0

詳解:return的時候已經先將返回值給定義下來了,就是0,由于i是在函數內部聲明所以即使在defer中進行了++操作,也不會影響return的時候做的決定。

func test() (i int)
func main() {
 fmt.Println("main:", test())
}
func test() (i int) {
 defer func() {
 i++
 fmt.Println("defer2的值:", i)
 }()
 defer func() {
 i++
 fmt.Println("defer1的值:", i)
 }()
 return i
}

輸出:

defer1的值: 1

defer2的值: 2

main: 2

詳解:由于返回值提前聲明了,所以在return的時候決定的返回值還是0,但是后面兩個defer執行后進行了兩次++,將i的值變為2,待defer執行完后,函數將i值進行了返回。

3.defer定義和執行兩個步驟,做的事情

先說結論:會先將defer后函數的參數部分的值(或者地址)給先下來【你可以理解為()里頭的會先確定】,后面函數執行完,才會執行defer后函數的{}中的邏輯

func test(i *int) int {
 return *i
}
func main(){
 var i = 1
 // defer定義的時候test(i)的值就已經定了,是1,后面就不會變了
 defer fmt.Println("i1 =" , test(i))
 i++
 // defer定義的時候test(i)的值就已經定了,是2,后面就不會變了
 defer fmt.Println("i2 =" , test(i))
 // defer定義的時候,i就已經確定了是一個指針類型,地址上的值變了,這里跟著變
 defer func(i *int) {
 fmt.Println("i3 =" , *i)
 }(i)
 // defer定義的時候i的值就已經定了,是2,后面就不會變了
 defer func(i int) {
 //defer 在定義的時候就定了
 fmt.Println("i4 =" , i)
 }(i)
 defer func() {
 // 地址,所以后續跟著變
 var c = i
 fmt.Println("i5 =" , *c)
 }()
 
 // 執行了 i=11 后才調用,此時i值已是11
 defer func() {
 fmt.Println("i6 =" , i)
 }()
 i = 11
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • 聊聊golang的defer的使用
  • Golang學習筆記之延遲函數(defer)的使用小結
  • golang中defer的關鍵特性示例詳解
  • golang中defer的使用規則詳解
  • Golang巧用defer進行錯誤處理的方法
  • Golang 的defer執行規則說明

標簽:電子產品 遼寧 青海 海南 西雙版納 物業服務 安康 儋州

巨人網絡通訊聲明:本文標題《Golang之defer 延遲調用操作》,本文關鍵詞  Golang,之,defer,延遲,調用,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Golang之defer 延遲調用操作》相關的同類信息!
  • 本頁收集關于Golang之defer 延遲調用操作的相關信息資訊供網民參考!
  • 推薦文章
    午夜久久网| 国产一区精品| 青青久久国产成人免费网站| 一级毛片看真人在线视频| 日韩在线观看免费| 一 级 黄 中国色 片| 国产视频在线免费观看| 亚飞与亚基在线观看| 国产不卡高清| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 亚洲精品影院一区二区| 亚欧乱色一区二区三区| 可以免费看污视频的网站| 精品视频在线观看一区二区三区| 欧美一区二区三区性| 精品视频在线观看免费| 一本高清在线| 国产一区二区精品久久| 日本特黄特黄aaaaa大片| 日韩av成人| 日韩av成人| 欧美国产日韩在线| 国产一区二区精品| 香蕉视频一级| 欧美另类videosbestsex久久| 国产高清视频免费观看| 黄视频网站在线观看| 一级女性大黄生活片免费| 亚洲精品影院一区二区| 欧美大片毛片aaa免费看| 青青久久网| 一级女性全黄生活片免费| 日韩免费片| 99久久网站| 黄色福利片| 欧美1区| 欧美α片无限看在线观看免费| 在线观看成人网| 欧美大片毛片aaa免费看| 日韩中文字幕一区二区不卡| 二级片在线观看| 欧美日本国产| 日本在线www| 99久久精品费精品国产一区二区| 久久久久久久网| 一 级 黄 中国色 片| 色综合久久天天综合观看| 国产麻豆精品hdvideoss| 久久99中文字幕| 久久国产精品只做精品| 高清一级片| 99热精品一区| 亚洲 欧美 成人日韩| a级精品九九九大片免费看| 九九免费精品视频| 国产一区二区高清视频| 高清一级片| 国产高清在线精品一区二区| 亚洲 男人 天堂| 亚洲不卡一区二区三区在线| 国产一级强片在线观看| 色综合久久久久综合体桃花网| 亚洲www美色| 午夜在线亚洲男人午在线| 免费的黄色小视频| 久久国产精品只做精品| 日韩av成人| 精品国产一级毛片| 一 级 黄 中国色 片| 国产亚洲免费观看| 国产麻豆精品免费密入口| 国产美女在线观看| 亚洲 国产精品 日韩| 国产成人精品一区二区视频| 亚洲 欧美 成人日韩| 精品视频在线观看免费| 黄视频网站在线观看| 成人影视在线观看| 日本特黄一级| 日韩在线观看视频网站| 深夜做爰性大片中文| 欧美大片毛片aaa免费看| 久久国产精品自由自在| 日本伦理网站| 欧美国产日韩在线| 国产a一级| 九九干| 国产视频一区在线| 亚洲 欧美 成人日韩| 亚洲第一页色| 黄视频网站在线观看| 国产a视频| 韩国三级香港三级日本三级la | 日韩在线观看视频黄| 精品久久久久久中文字幕一区| 精品国产一区二区三区免费 | 99久久精品费精品国产一区二区| 日本伦理网站| 国产高清在线精品一区二区| 欧美爱色| 日韩中文字幕一区| 99热视热频这里只有精品| 久久99爰这里有精品国产| 亚洲第一视频在线播放| 国产成a人片在线观看视频| 国产成a人片在线观看视频| 色综合久久久久综合体桃花网| 精品久久久久久免费影院| 国产视频久久久| 久久国产一区二区| 国产极品精频在线观看| 亚洲精品久久玖玖玖玖| 国产91丝袜高跟系列| 国产福利免费观看| 成人高清视频免费观看| 国产视频久久久| 国产成人精品一区二区视频| 精品视频免费在线| 久草免费在线色站| 91麻豆精品国产自产在线| 可以在线看黄的网站| 精品国产一级毛片| 久久久久久久网| 欧美激情在线精品video| 欧美爱色| 99久久网站| 久久久久久久网| 久久国产精品自由自在| 91麻豆精品国产综合久久久| 香蕉视频一级| 999久久久免费精品国产牛牛| 国产欧美精品午夜在线播放| 国产一区精品| 国产国产人免费视频成69堂| 黄视频网站在线免费观看| 国产一区二区精品久久91| 九九九国产| 亚洲精品影院一区二区| 成人在免费观看视频国产| 精品视频免费在线| 欧美激情一区二区三区在线播放| 在线观看成人网| 国产国语在线播放视频| 九九免费精品视频| 成人影视在线观看| 999久久66久6只有精品| 国产伦久视频免费观看视频| 国产精品免费精品自在线观看| 999精品影视在线观看| 日本特黄一级| 精品视频在线观看一区二区三区| 免费毛片播放| 一级片片| 91麻豆国产福利精品| 一本高清在线| 亚洲精品久久玖玖玖玖| 国产91精品一区| 亚飞与亚基在线观看| 日韩免费在线视频| 欧美a级片免费看| 成人免费网站视频ww| 深夜做爰性大片中文| 青青久久网| 999久久久免费精品国产牛牛| 日本特黄一级| 精品国产亚洲人成在线| 精品视频免费在线| 欧美激情伊人| 欧美α片无限看在线观看免费| 国产一区二区精品久久91| 精品国产亚洲人成在线| 99久久精品国产国产毛片| 尤物视频网站在线观看| 一级女性全黄生活片免费| 精品国产一区二区三区久久久狼| 中文字幕97| 色综合久久天天综合绕观看| 可以在线看黄的网站| 一本高清在线| 国产麻豆精品免费密入口| 可以免费看污视频的网站| 可以在线看黄的网站| 国产伦久视频免费观看视频| 精品国产香蕉在线播出| 亚洲 男人 天堂| 日韩在线观看视频网站| 欧美一区二区三区性| 黄视频网站免费观看| 色综合久久天天综合绕观看| 成人在免费观看视频国产| 亚洲精品中文一区不卡| 日本伦理网站| 国产一区精品| 日韩中文字幕一区| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 国产精品免费精品自在线观看| 天天色色网| 免费国产在线观看不卡| 久久久成人影院| 国产一区二区高清视频|