濮阳杆衣贸易有限公司

主頁 > 知識庫 > 深入理解Go語言中的閉包

深入理解Go語言中的閉包

熱門標(biāo)簽:浙江高頻外呼系統(tǒng)多少錢一個月 黃岡人工智能電銷機(jī)器人哪個好 汕頭小型外呼系統(tǒng) 鄭州亮點科技用的什么外呼系統(tǒng) 惠州電銷防封電話卡 建造者2地圖標(biāo)注 釘釘有地圖標(biāo)注功能嗎 阿里云ai電話機(jī)器人 濱州自動電銷機(jī)器人排名

閉包

在函數(shù)編程中經(jīng)常用到閉包,閉包是什?它是怎么產(chǎn)生的及用來解決什么問題呢?先給出閉包的字面定義:閉包是由函數(shù)及其相關(guān)引用環(huán)境組合而成的實體(即:閉包=函數(shù)+引用環(huán)境)。這個從字面上很難理解,特別對于一直使用命令式語言進(jìn)行編程的程序員們。

Go語言中的閉包

先看一個demo:

func f(i int) func() int {
 return func() int {
 i++
 return i
 }
}

函數(shù)f返回了一個函數(shù),返回的這個函數(shù)就是一個閉包。這個函數(shù)中本身是沒有定義變量i的,而是引用了它所在的環(huán)境(函數(shù)f)中的變量i。

我們再看一下效果:

c1 := f(0)
c2 := f(0)
c1() // reference to i, i = 0, return 1
c2() // reference to another i, i = 0, return 1

c1跟c2引用的是不同的環(huán)境,在調(diào)用i++時修改的不是同一個i,因此兩次的輸出都是1。函數(shù)f每進(jìn)入一次,就形成了一個新的環(huán)境,對應(yīng)的閉包中,函數(shù)都是同一個函數(shù),環(huán)境卻是引用不同的環(huán)境。

變量i是函數(shù)f中的局部變量,假設(shè)這個變量是在函數(shù)f的棧中分配的,是不可以的。因為函數(shù)f返回以后,對應(yīng)的棧就失效了,f返回的那個函數(shù)中變量i就引用一個失效的位置了。所以閉包的環(huán)境中引用的變量不能夠在棧上分配。

escape analyze

在繼續(xù)研究閉包的實現(xiàn)之前,先看一看Go的一個語言特性:

func f() *Cursor {
 var c Cursor
 c.X = 500
 noinline()
 return c
}

Cursor是一個結(jié)構(gòu)體,這種寫法在C語言中是不允許的,因為變量c是在棧上分配的,當(dāng)函數(shù)f返回后c的空間就失效了。但是,在Go語言規(guī)范中有說明,這種寫法在Go語言中合法的。語言會自動地識別出這種情況并在堆上分配c的內(nèi)存,而不是函數(shù)f的棧上。

為了驗證這一點,可以觀察函數(shù)f生成的匯編代碼:

MOVQ $type."".Cursor+0(SB),(SP) // 取變量c的類型,也就是Cursor
PCDATA $0,$16
PCDATA $1,$0
CALL ,runtime.new(SB) // 調(diào)用new函數(shù),相當(dāng)于new(Cursor)
PCDATA $0,$-1
MOVQ 8(SP),AX // 取c.X的地址放到AX寄存器
MOVQ $500,(AX) // 將AX存放的內(nèi)存地址的值賦為500
MOVQ AX,"".~r0+24(FP)
ADDQ $16,SP

識別出變量需要在堆上分配,是由編譯器的一種叫escape analyze的技術(shù)實現(xiàn)的。

如果輸入命令:

go build --gcflags=-m main.go

可以看到輸出:

注意:最后兩行,標(biāo)識c逃逸了,被移動到堆中。escape analyze可以分析出變量的作用范圍,這是對垃圾回收很重要的一項技術(shù)。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

您可能感興趣的文章:
  • GO語io包的常用接口
  • Go語言的os包中常用函數(shù)初步歸納
  • 舉例講解Go語言中函數(shù)的閉包使用
  • go語言里包的用法實例
  • Go語言聲明一個多行字符串的變量
  • Go語言基礎(chǔ)知識總結(jié)(語法、變量、數(shù)值類型、表達(dá)式、控制結(jié)構(gòu)等)
  • GO語言獲取系統(tǒng)環(huán)境變量的方法
  • Go語言中的變量聲明和賦值
  • 詳解Golang編程中的常量與變量
  • go語言學(xué)習(xí)之包和變量詳解

標(biāo)簽:泰安 瀘州 駐馬店 昭通 滄州 阿壩 晉中 東營

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《深入理解Go語言中的閉包》,本文關(guān)鍵詞  深入,理解,語言,中的,閉包,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《深入理解Go語言中的閉包》相關(guān)的同類信息!
  • 本頁收集關(guān)于深入理解Go語言中的閉包的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    二手房| 平罗县| 江陵县| 赤城县| 盐山县| 白城市| 腾冲县| 鄂托克前旗| 阳信县| 芮城县| 高州市| 华坪县| 锡林浩特市| 敦化市| 灵武市| 苍山县| 绥江县| 洪江市| 错那县| 甘南县| 扎兰屯市| 阿坝| 大宁县| 沁阳市| 肥西县| 县级市| 金塔县| 阳原县| 大宁县| 庄浪县| 高邮市| 南昌市| 西城区| 香港 | 贵阳市| 鄂尔多斯市| 林西县| 曲阜市| 广安市| 大方县| 岢岚县|