go的defer和閉包示例說明(非內(nèi)部實現(xiàn))
golang的閉包函數(shù)
用幾個例子說明golang的閉包函數(shù),結(jié)合defer使用,配合對應(yīng)代碼及文末總結(jié)。
| 函數(shù) | 說明 | 輸出 |
|---|---|---|
| e1 | defer調(diào)用,相當于是拿到了當前err變量的快照,即注冊defer函數(shù)的時候,將當下err的值塞入到defer中 | start err1 |
| e2 | defer 調(diào)用,但是一個閉包函數(shù),且閉包函數(shù)有傳參,閉包捕獲當前err的值仍然是 start err2(閉包捕獲的是變量值的拷貝),且閉包內(nèi)的值變量改變不會影響外部err的值(詳見見e5) | start err2 |
| e3 | defer 調(diào)用,閉包內(nèi)的變量和匿名函數(shù)外的變量是公用的,沒有傳遞形參,沒有傳遞形參,與上下文共享 | defer3 error |
| e4 | defer 調(diào)用,在函數(shù) e4 中,當你將 err 作為參數(shù)傳遞給閉包函數(shù)時,實際上是創(chuàng)建了一個閉包函數(shù)的副本,這個副本在閉包內(nèi)部獨立于外部作用域。這種行為是因為閉包在捕獲外部變量時,會將外部變量的當前值復(fù)制到閉包內(nèi)部,形成一個閉包環(huán)境,現(xiàn)在理解了閉包的概念了吧。具體來說,在 defer 語句執(zhí)行的時候,閉包函數(shù)會將 err 的當前值(即 "start err4")復(fù)制到閉包內(nèi)部的參數(shù)中。之后,無論外部作用域的 err 是否發(fā)生改變,閉包內(nèi)部的參數(shù)值都會保持不變,因為閉包已經(jīng)捕獲了一個快照 | start err4 |
| e5 | 傳值的情況下,閉包內(nèi)的值變量改變不會影響外部err的值,(互相獨立) | now err is start err5 start err5CHANGE ME |
| e6 | 閉包沒有傳值,拿到的err是最后賦值的, | now err is start err6 defer6 error CHANGE ME |
package main
import (
"errors"
"fmt"
)
func e1(){
err := errors.New("start err1")
defer fmt.Println(err)
err = errors.New("defer1 error")
return
}
func e2(){
err := errors.New("start err2")
defer func(e error) {
fmt.Println(e)
}(err)
err = errors.New("defer2 error")
return
}
func e3(){
err := errors.New("start err3")
//閉包內(nèi)的變量和匿名函數(shù)外的變量是公用的,沒有傳遞形參,沒有傳遞形參,與上下文共享
defer func() {
fmt.Println(err)
}()
err = errors.New("defer3 error")
return
}
func e4(){
var err error
err = errors.New("start err4")
//閉包內(nèi)的變量和匿名函數(shù)外的變量是公用的,但是如果傳了形參,那就和上文的共用了
//在函數(shù) e4 中,當你將 err 作為參數(shù)傳遞給閉包函數(shù)時,實際上是創(chuàng)建了一個閉包函數(shù)的副本,這個副本在閉包內(nèi)部獨立于外部作用域。這種行為是因為閉包在捕獲外部變量時,會將外部變量的當前值復(fù)制到閉包內(nèi)部,形成一個閉包環(huán)境
//具體來說,在 defer 語句執(zhí)行的時候,閉包函數(shù)會將 err 的當前值(即 "start err4")復(fù)制到閉包內(nèi)部的參數(shù)中。之后,無論外部作用域的 err 是否發(fā)生改變,閉包內(nèi)部的參數(shù)值都會保持不變,因為閉包已經(jīng)捕獲了一個快照。
defer func(err error) {
fmt.Println(err)
}(err)
err = errors.New("defer4 error")
return
}
func e5(){
err := errors.New("start err4")
defer func(err error ) {
err=errors.New(err.Error()+"CHANGE ME")
fmt.Println(err)
}(err)
fmt.Println("now err is ",err)
err = errors.New("defer5 error")
return
}
func e6() {
err := errors.New("start err6")
defer func() {
err = errors.New(err.Error() + " CHANGE ME")
fmt.Println(err)
}()
fmt.Println("now err is ", err)
err = errors.New("defer6 error")
return
}
func main(){
e1()
e2()
e3()
e4()
e5()
e6()
}變量作用域和閉包
Go 語言中的變量作用域由代碼塊決定。變量在其定義的代碼塊內(nèi)可見。
閉包是一個函數(shù)值,它可以捕獲其定義時周圍的作用域內(nèi)的變量。
閉包可以在定義之外被調(diào)用,仍然訪問并修改捕獲的變量。
閉包和變量捕獲
閉包函數(shù)可以捕獲外部作用域的變量。在閉包內(nèi)部,它們可以訪問外部變量的值。
閉包捕獲的變量是其副本,即閉包內(nèi)部使用的是變量值的拷貝。
修改閉包內(nèi)部捕獲的變量不會影響外部作用域中的變量,除非你在閉包內(nèi)直接修改外部作用域的變量。
閉包參數(shù)傳遞
在閉包內(nèi)部接收外部作用域的變量作為參數(shù),可以使閉包操作外部作用域的變量。
使用閉包參數(shù)傳遞可以有效隔離閉包內(nèi)外的變量,從而保持可預(yù)測性。
在 defer 中的閉包
當在 defer 語句中使用閉包時,閉包內(nèi)部的變量會被“捕獲”并在 defer 執(zhí)行時使用。
在閉包內(nèi)部修改閉包捕獲的變量不會影響外部作用域中的變量,除非你直接修改外部作用域的變量。
總結(jié)
閉包是一種強大的概念,可以使函數(shù)擁有狀態(tài)并延遲執(zhí)行。
了解閉包如何操作變量作用域,以及它們?nèi)绾尾东@和修改變量,是編寫高效、清晰的 Go 代碼的關(guān)鍵。
當在閉包中操作變量時,要注意變量作用域、捕獲的變量副本和對外部作用域的影響。
以上就是go的defer和閉包示例說明(非內(nèi)部實現(xiàn))的詳細內(nèi)容,更多關(guān)于go defer閉包的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang踩坑實戰(zhàn)之channel的正確使用方式
Golang?channel是Go語言中一個非常重要的特性,除了用來處理并發(fā)編程的任務(wù)中,它還可以用來進行消息傳遞和事件通知,這篇文章主要給大家介紹了關(guān)于golang踩坑實戰(zhàn)之channel的正確使用方式,需要的朋友可以參考下2023-06-06
golang的時區(qū)和神奇的time.Parse的使用方法
這篇文章主要介紹了golang的時區(qū)和神奇的time.Parse的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Go并發(fā)的方法之goroutine模型與調(diào)度策略
在go中,協(xié)程co-routine被改為goroutine,一個goroutine只占幾kb,因此可以有大量的goroutine存在,另一方面goroutine 的調(diào)度器非常靈活,本文給大家介紹下Go并發(fā)的方法之goroutine模型與調(diào)度策略,感興趣的朋友一起看看吧2021-11-11
獲取Golang環(huán)境變量的三種方式小結(jié)
本文介紹了Golang中獲取環(huán)境變量的三種方式,包含使用Viper包、GoDotEnv包和os包,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11
Golang unsafe.Sizeof函數(shù)代碼示例使用解析
這篇文章主要為大家介紹了Golang unsafe.Sizeof函數(shù)代碼示例使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12
golang包循環(huán)引用的幾種解決方案總結(jié)
golang有包循環(huán)引用問題,用過的應(yīng)該都知道,下面這篇文章主要給大家介紹了關(guān)于golang包循環(huán)引用的幾種解決方案,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-09-09

