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

簡(jiǎn)單聊聊Golang中defer預(yù)計(jì)算參數(shù)

 更新時(shí)間:2022年03月25日 16:53:18   作者:藍(lán)色記憶  
在golang當(dāng)中defer代碼塊會(huì)在函數(shù)調(diào)用鏈表中增加一個(gè)函數(shù)調(diào)用,下面這篇文章主要給大家介紹了關(guān)于Golang中defer預(yù)計(jì)算參數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

什么是defer

defer用來(lái)聲明一個(gè)延遲函數(shù),把這個(gè)函數(shù)放入到一個(gè)棧上, 當(dāng)外部的包含方法return之前,返回參數(shù)到調(diào)用方法之前調(diào)用,也可以說(shuō)是運(yùn)行到最外層方法體的"}"時(shí)調(diào)用。我們經(jīng)常用他來(lái)做一些資源的釋放,比如關(guān)閉io操作

func doSomething(fileName string) {
    file,err := os.Open(fileName)
    if err != nil {
    panic(err)
    }
    defer file.Close()
}

defer 可以保證方法可以在外圍函數(shù)返回之前調(diào)用。有點(diǎn)像其他言的 try finally

try{
}finally{
}

Go語(yǔ)言defer預(yù)計(jì)算參數(shù)

Go 語(yǔ)言中所有的函數(shù)調(diào)用都是傳值的,雖然 defer 是關(guān)鍵字,但是也繼承了這個(gè)特性。假設(shè)我們想要計(jì)算 main 函數(shù)運(yùn)行的時(shí)間,可能會(huì)寫(xiě)出以下的代碼:

package main
import (
	"fmt"
	"time"
)

func main() {
	startedAt := time.Now()
	defer fmt.Println(time.Since(startedAt))
	time.Sleep(time.Second) //休眠一秒
} 

結(jié)果是:

D:\workspace\go\src\test>go run main.go
0s 

運(yùn)行結(jié)果并不符合我們的預(yù)期,這個(gè)現(xiàn)象背后的原因是什么呢?經(jīng)過(guò)分析,我們會(huì)發(fā)現(xiàn)調(diào)用 defer 關(guān)鍵字會(huì)立刻拷貝函數(shù)中引用的外部參數(shù),所以 time.Since(startedAt) 的結(jié)果不是在 main 函數(shù)退出之前計(jì)算的,而是在 defer 關(guān)鍵字調(diào)用時(shí)計(jì)算的【defer入棧的時(shí)候】,最終導(dǎo)致上述代碼輸出 0s

我們?cè)賮?lái)看個(gè)簡(jiǎn)單例子來(lái)說(shuō)明上述解釋?zhuān)?/p>

package main
import (
	"fmt"
)

func main() {
	i := 1
	defer fmt.Println(test(i))
	i = 100
}

func test(i int) int {
	i = i + 1
	return i
} 

D:\workspace\go\src\test>go run main.go
2 

當(dāng)代碼運(yùn)行到defer fmt.Println(test(i))的時(shí)候,會(huì)把defer右邊最外層函數(shù)的參數(shù)計(jì)算完畢,并傳遞進(jìn)函數(shù)里,但不會(huì)執(zhí)行函數(shù)體的代碼直到包裹defer的函數(shù)返回。我們先看會(huì)把defer右邊最外層函數(shù)的參數(shù)計(jì)算完畢,并傳遞進(jìn)函數(shù)里這句話,對(duì)應(yīng)例子就是先把test(i)算出來(lái),此時(shí)i=1,計(jì)算test(1)得2,然后fmt.Println(2)入棧,等到最后程序運(yùn)行完了再運(yùn)行defer結(jié)果就是2(但不會(huì)執(zhí)行函數(shù)體的代碼直到包裹defer的函數(shù)返回)。

我們?cè)賮?lái)看一個(gè)例子與匿名函數(shù)結(jié)合:

package main
import (
	"fmt"
)

func main() {
	i := 1
	defer func() {
		fmt.Println(test(i))
	}()
	i = 100
}

func test(i int) int {
	i = i + 1
	return i
} 

結(jié)果:

D:\workspace\go\src\test>go run main.go
101  

使用匿名函數(shù),結(jié)果是101,相當(dāng)于i給到test方法的是100,那為什么呢?還是那句話:但不會(huì)執(zhí)行函數(shù)體的代碼直到包裹defer的函數(shù)返回

也就是說(shuō)他會(huì)把整個(gè){ fmt.Println(test(i)) }()函數(shù)體入棧,等到最后程序運(yùn)行完了再運(yùn)行defer,此時(shí)的i是100,運(yùn)行test后就是101了。

所以你要解決第一個(gè)打印為0s的問(wèn)題,你就可以使用匿名函數(shù)來(lái)解決,如下:

package main
import (
	"fmt"
	"time"
)

func main() {
	startedAt := time.Now()
	defer func() {
		fmt.Println(time.Since(startedAt))
	}()
	time.Sleep(time.Second) //休眠一秒
} 

結(jié)果:

D:\workspace\go\src\test>go run main.go
1.0152825s

總結(jié)

到此這篇關(guān)于Golang中defer預(yù)計(jì)算參數(shù)的文章就介紹到這了,更多相關(guān)Go defer預(yù)計(jì)算參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

    node_exporter這個(gè)開(kāi)源組件是配合prometheus收集主機(jī)操作系統(tǒng)層的metrics的常用組件,但是官方?jīng)]有提供GPU卡的metrics的采集,今天通過(guò)本文給大家介紹golang通過(guò)node_exporter監(jiān)控GPU及cpu頻率、溫度的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2022-05-05
  • go mock模擬接口的實(shí)現(xiàn)

    go mock模擬接口的實(shí)現(xiàn)

    本文主要介紹了go mock模擬接口的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • GoLang完整實(shí)現(xiàn)快速列表

    GoLang完整實(shí)現(xiàn)快速列表

    這篇文章主要介紹了GoLang完整實(shí)現(xiàn)快速列表,列表是一種非連續(xù)的存儲(chǔ)容器,由多個(gè)節(jié)點(diǎn)組成,節(jié)點(diǎn)通過(guò)一些 變量 記錄彼此之間的關(guān)系,列表有多種實(shí)現(xiàn)方法,如單鏈表、雙鏈表等
    2022-12-12
  • Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    這篇文章主要介紹了Golang中Bit數(shù)組的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Golang初始化MySQL數(shù)據(jù)庫(kù)方法淺析

    Golang初始化MySQL數(shù)據(jù)庫(kù)方法淺析

    這篇文章主要介紹了Golang初始化MySQL數(shù)據(jù)庫(kù)的方法,數(shù)據(jù)庫(kù)的建立第一步即要初始化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-05-05
  • Go語(yǔ)言fmt.Sprintf格式化輸出的語(yǔ)法與實(shí)例

    Go語(yǔ)言fmt.Sprintf格式化輸出的語(yǔ)法與實(shí)例

    Go 可以使用 fmt.Sprintf 來(lái)格式化字符串,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言fmt.Sprintf格式化輸出的語(yǔ)法與實(shí)例,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Go工具鏈之go tool fix用法詳解

    Go工具鏈之go tool fix用法詳解

    go tool fix 是 Go 工具鏈中的一個(gè)命令,作用是把指定 Go 程序代碼包中的的所有舊版本代碼修正為新版本的代碼,本文將簡(jiǎn)單介紹一下go tool fix的使用方法,感興趣的小伙伴可以參考閱讀下
    2023-07-07
  • Go并發(fā)控制Channel使用場(chǎng)景分析

    Go并發(fā)控制Channel使用場(chǎng)景分析

    使用channel來(lái)控制子協(xié)程的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,缺點(diǎn)是當(dāng)需要大量創(chuàng)建協(xié)程時(shí)就需要有相同數(shù)量的channel,而且對(duì)于子協(xié)程繼續(xù)派生出來(lái)的協(xié)程不方便控制
    2021-07-07
  • 詳解go-zero是如何做路由管理的

    詳解go-zero是如何做路由管理的

    go-zero 是一個(gè)微服務(wù)框架,包含了 web 和 rpc 兩大部分,而對(duì)于 web 框架來(lái)說(shuō),路由管理是必不可少的一部分,那么本文就來(lái)探討一下 go-zero 的路由管理是怎么做的吧
    2023-08-08
  • Go語(yǔ)言實(shí)現(xiàn)配置熱加載的方法分享

    Go語(yǔ)言實(shí)現(xiàn)配置熱加載的方法分享

    web項(xiàng)目,經(jīng)常需要熱啟動(dòng)各種各樣的配置信息,一旦這些服務(wù)發(fā)生變更,我們需要重新啟動(dòng)web server,以使配置生效,實(shí)現(xiàn)配置熱加載,本文為大家整理了幾個(gè)方法實(shí)現(xiàn)這個(gè)需求,需要的可以參考下
    2023-05-05

最新評(píng)論