Golang中的閉包(Closures)詳解
在講解閉包之前先看一下 Golang 中的匿名函數(shù)。
匿名函數(shù)(Anonymous Functions)
匿名函數(shù)也可以稱為函數(shù)字面量、lambda 函數(shù)或者閉包。閉包的概念起源于 lambda 微積分中表達(dá)式的數(shù)學(xué)求值。從技術(shù)上講,匿名函數(shù)和閉包之間有細(xì)微的區(qū)別:匿名函數(shù)是沒有名稱的函數(shù),而閉包則是函數(shù)的實(shí)例。在 Golang 中要實(shí)現(xiàn)閉包,是離不開匿名函數(shù)的。
先看一個(gè)普通函數(shù)的例子,例如:
func add(x, y int) {
fmt.Println(x + y)
}調(diào)用方式如下:
add(1, 2) // 輸出 3
接下來看下如何使用匿名函數(shù)來實(shí)現(xiàn)相同的功能:
func(x, y int) {
fmt.Println(x + y)
}(1, 2)這個(gè)匿名函數(shù)和上面的普通的函數(shù)的功能是一樣的,區(qū)別是
- 沒有名字
- 定義之后就直接調(diào)用
接下來,使用通過創(chuàng)建一個(gè)返回一個(gè)函數(shù)的函數(shù)的方式來使用一個(gè)匿名函數(shù)。函數(shù)一般都是返回整數(shù)、字符串、結(jié)構(gòu)體等基本類型,但是在 Golang 中一個(gè)函數(shù)可以返回另一個(gè)函數(shù)。如下是 Golang 官方的一個(gè)例子:
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}這個(gè)函數(shù)的返回類型是 func(int) int 類型的函數(shù),可以將這個(gè)函數(shù)的返回值賦值給一個(gè)變量,然后可以像調(diào)用一個(gè)函數(shù)的方式使用調(diào)用這個(gè)變量,例如:
pos := adder() pos(1)
閉包(Closures)
通過上文的講解我們已經(jīng)知道了匿名函數(shù)的定義以及使用方式,也了解了一個(gè)函數(shù)可以返回另一個(gè)函數(shù),接下來講解下閉包。
在 Golang 中,閉包是一個(gè)引用了作用域之外的變量的函數(shù)。閉包的存在時(shí)間可以超過創(chuàng)建它的作用域,因此它可以訪問該作用域中的變量,即使在該作用域被銷毀之后。上文中的 adder() 函數(shù)返回的就是一個(gè)典型的閉包。
Golang 中的匿名函數(shù)也被稱為閉包,匿名函數(shù)是一種特殊類型的函數(shù),沒有名稱,閉包可以被認(rèn)為是一種特殊類型的匿名函數(shù)。
Golang 中的閉包由兩部分組成:函數(shù)體和函數(shù)執(zhí)行時(shí)的上下文環(huán)境。函數(shù)體定義了閉包的邏輯,上下文環(huán)境則包含了函數(shù)外部的變量。當(dāng)閉包被創(chuàng)建時(shí),會(huì)將外部變量的引用保存在上下文環(huán)境中,并且在函數(shù)體內(nèi)部可以隨時(shí)訪問這些外部變量。看個(gè)將上文中的 adder() 函數(shù)稍作修改的例子:
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
fmt.Println("執(zhí)行前 sum =", sum)
sum += x
return sum
}
}
func main() {
pos := adder()
for i := 0; i < 4; i++ {
fmt.Println("執(zhí)行后 sum =", pos(1))
}
}運(yùn)行結(jié)果如下:
執(zhí)行前 sum = 0
執(zhí)行后 sum = 1
執(zhí)行前 sum = 1
執(zhí)行后 sum = 2
執(zhí)行前 sum = 2
執(zhí)行后 sum = 3
執(zhí)行前 sum = 3
執(zhí)行后 sum = 4
可以看出,閉包函數(shù)引用的外部變量被保存在了上下文環(huán)境中(一直不被銷毀),每次執(zhí)行閉包,閉包內(nèi)的變量又保存了上一次運(yùn)行后的值。
小結(jié)
閉包是來源于函數(shù)式編程語言的一種特性,函數(shù)既可以返回一個(gè)函數(shù)、也可以接受一個(gè)函數(shù)作為參數(shù)(這種函數(shù)被稱為高階函數(shù))。Golang也支持函數(shù)式編程,閉包在Golang 中有非常廣泛的使用,并且經(jīng)常與Goroutine 和 channel 一起使用。
到此這篇關(guān)于Golang中的閉包(Closures)詳解的文章就介紹到這了,更多相關(guān)Golang閉包(Closures)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go語言中嵌套結(jié)構(gòu)體的實(shí)現(xiàn)
在Go語言中,嵌套結(jié)構(gòu)體可定義為一個(gè)結(jié)構(gòu)體內(nèi)包含另一個(gè)結(jié)構(gòu)體,嵌套可以是值嵌套或指針嵌套,兩者在內(nèi)存分配和修改影響上有顯著區(qū)別,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下2024-09-09
go json數(shù)據(jù)轉(zhuǎn)發(fā)的實(shí)現(xiàn)代碼
這篇文章主要介紹了go json數(shù)據(jù)轉(zhuǎn)發(fā)的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
go select編譯期的優(yōu)化處理邏輯使用場景分析
select 是 Go 中的一個(gè)控制結(jié)構(gòu),類似于用于通信的 switch 語句。每個(gè) case 必須是一個(gè)通信操作,要么是發(fā)送要么是接收。接下來通過本文給大家介紹go select編譯期的優(yōu)化處理邏輯使用場景分析,感興趣的朋友一起看看吧2021-06-06
使用Golang實(shí)現(xiàn)AES加解密的代碼示例
在現(xiàn)代的數(shù)據(jù)安全中,加密和解密是極其重要的一環(huán),其中,高級(jí)加密標(biāo)準(zhǔn)(AES)是最廣泛使用的加密算法之一,本文將介紹如何使用Golang來實(shí)現(xiàn)AES加密和解密,需要的朋友可以參考下2024-04-04

