溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Golang函數(shù)中defer的作用以及細(xì)節(jié)

發(fā)布時(shí)間:2020-07-16 09:25:03 來源:網(wǎng)絡(luò) 閱讀:350 作者:GoDevops 欄目:編程語言

defer是什么?

    在Go語言中,可以使用關(guān)鍵字defer向函數(shù)注冊(cè)退出調(diào)用,即主函數(shù)退出時(shí),defer后的函數(shù)才被調(diào)用。defer語句的作用是不管程序是否出現(xiàn)異常,均在函數(shù)退出時(shí)自動(dòng)執(zhí)行相關(guān)代碼。 

defer的用途

在函數(shù)中,程序員經(jīng)常需要?jiǎng)?chuàng)建資源(比如:數(shù)據(jù)庫連接、文件句柄、鎖等) ,為了在函數(shù)執(zhí)行完 畢后,及時(shí)的釋放資源,Go 的設(shè)計(jì)者提供 defer (延時(shí)機(jī)制)

package main

import "fmt"
//defer  可以向函數(shù)注冊(cè)、退出調(diào)用,即當(dāng)主調(diào)函數(shù)退出時(shí),defer后的函數(shù)才被調(diào)用,
// defer語句的作用就是不管程序是否出現(xiàn)異常,均在函數(shù)退出是自動(dòng)執(zhí)行相關(guān)代碼

func sum(n1 int,n2 int) int{
   //當(dāng)執(zhí)行到defer時(shí),暫時(shí)不執(zhí)行,會(huì)將defer后面的語句壓入到獨(dú)立的(defer棧)
   //當(dāng)函數(shù)執(zhí)行完畢后,再從defer棧 安裝先入后出的方式出棧執(zhí)行
   //defer 將語句放入到棧時(shí),也會(huì)將相關(guān)的值拷貝同時(shí)入棧***
   defer  fmt.Println("ok1 n1=",n1)//defer3   ok3   n1  20
   defer  fmt.Println("ok2 n2=",n2) //defer2  ok2 n2  10
   //n1 ++
   //n2 ++

    res := n1 + n2
    fmt.Println("ok3 res=",res)//1.ok1
    return  res
}
func  main()  {
   res :=sum(20,10)
   fmt.Println("res=",res)

}

執(zhí)行結(jié)果

Golang函數(shù)中defer的作用以及細(xì)節(jié)

結(jié)果分析:

   從執(zhí)行結(jié)果來看,res=30 是最先開始執(zhí)行的部分,接下來是第二個(gè)defer n2為10 最后執(zhí)行的是第一個(gè)defer n1為20 ,即當(dāng)執(zhí)行到defer時(shí),暫時(shí)不執(zhí)行,會(huì)將defer后面的語句壓入到獨(dú)立的(defer棧),當(dāng)函數(shù)執(zhí)行完畢后,再從defer棧,按照(先入后出)的方式出棧執(zhí)行。


注意事項(xiàng):

1) 當(dāng) go 執(zhí)行到一個(gè) defer 時(shí),不會(huì)立即執(zhí)行 defer 后的語句,而是將 defer 后的語句壓入到一個(gè)棧 中[我為了講課方便,暫時(shí)稱該棧為 defer ], 然后繼續(xù)執(zhí)行函數(shù)下一個(gè)語句。

2) 當(dāng)函數(shù)執(zhí)行完畢后,在從 defer 棧中,依次從棧頂取出語句執(zhí)行(注:遵守棧 先入后出的機(jī)制),

3) defer 將語句放入到棧時(shí),也會(huì)將相關(guān)的值拷貝同時(shí)入棧

package main

import "fmt"
//defer  可以向函數(shù)注冊(cè)、退出調(diào)用,即當(dāng)主調(diào)函數(shù)退出時(shí),defer后的函數(shù)才被調(diào)用,
// defer語句的作用就是不管程序是否出現(xiàn)異常,均在函數(shù)退出是自動(dòng)執(zhí)行相關(guān)代碼

func sum(n1 int,n2 int) int{
   //當(dāng)執(zhí)行到defer時(shí),暫時(shí)不執(zhí)行,會(huì)將defer后面的語句壓入到獨(dú)立的(defer棧)
   //當(dāng)函數(shù)執(zhí)行完畢后,再從defer棧 安裝先入后出的方式出棧執(zhí)行
   //defer 將語句放入到棧時(shí),也會(huì)將相關(guān)的值拷貝同時(shí)入棧***
   defer  fmt.Println("ok1 n1=",n1)//defer3   ok3   n1  20
   defer  fmt.Println("ok2 n2=",n2) //defer2  ok2 n2  10
   n1 ++
   n2 ++

    res := n1 + n2
    fmt.Println("ok3 res=",res)//1.ok1
    return  res
}
func  main()  {
   res :=sum(20,10)
   fmt.Println("res=",res)

}

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

Golang函數(shù)中defer的作用以及細(xì)節(jié)

從結(jié)果看出n1++ ,n2++兩個(gè)的值未入相關(guān)defer的棧,即defer 將語句放入到棧時(shí),也會(huì)將相關(guān)的值拷貝同時(shí)入棧。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI