在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳細(xì)介紹go語言中的閉包的實現(xiàn)

馬哥Linux運維 ? 來源:tiancaiamao ? 作者:tiancaiamao ? 2021-10-20 16:18 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

什么是閉包?什么場景下會用閉包
本文對go 語言中的閉包做了詳細(xì)介紹。

閉包是由函數(shù)及其相關(guān)引用環(huán)境組合而成的實體(即:閉包=函數(shù)+引用環(huán)境)。

Go中的閉包

閉包是函數(shù)式語言中的概念,沒有研究過函數(shù)式語言的用戶可能很難理解閉包的強大,相關(guān)的概念超出了本書的范圍。Go語言是支持閉包的,這里只是簡單地講一下在Go語言中閉包是如何實現(xiàn)的。

funcf(iint)func()int{
returnfunc()int{
i++
returni
}
}

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

c1:=f(0)
c2:=f(0)
c1()//referencetoi,i=0,return1
c2()//referencetoanotheri,i=0,return1

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的一個語言特性:

funcf()*Cursor{
varcCursor
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
MOVQ8(SP),AX//取c.X的地址放到AX寄存器
MOVQ$500,(AX)//將AX存放的內(nèi)存地址的值賦為500
MOVQAX,"".~r0+24(FP)
ADDQ$16,SP

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

gobuild--gcflags=-mmain.go

可以看到輸出:

./main.gomovedtoheap:c
./main.go&cescapestoheap

表示c逃逸了,被移到堆中。escape analyze可以分析出變量的作用范圍,這是對垃圾回收很重要的一項技術(shù)。

閉包結(jié)構(gòu)體

回到閉包的實現(xiàn)來,前面說過,閉包是函數(shù)和它所引用的環(huán)境。那么是不是可以表示為一個結(jié)構(gòu)體呢:

typeClosurestruct{
Ffunc()()
i*int
}

事實上,Go在底層確實就是這樣表示一個閉包的。讓我們看一下匯編代碼:

funcf(iint)func()int{
returnfunc()int{
i++
returni
}
}


MOVQ$type.int+0(SB),(SP)
PCDATA$0,$16
PCDATA$1,$0
CALL,runtime.new(SB)//是不是很熟悉,這一段就是i=new(int)
...
MOVQ$type.struct{Fuintptr;A0*int}+0(SB),(SP)//這個結(jié)構(gòu)體就是閉包的類型
...
CALL,runtime.new(SB)//接下來相當(dāng)于new(Closure)
PCDATA$0,$-1
MOVQ8(SP),AX
NOP,
MOVQ$"".func·001+0(SB),BP
MOVQBP,(AX)//函數(shù)地址賦值給Closure的F部分
NOP,
MOVQ"".&i+16(SP),BP//將堆中new的變量i的地址賦值給Closure的值部分
MOVQBP,8(AX)
MOVQAX,"".~r1+40(FP)
ADDQ$24,SP
RET,

其中func·001是另一個函數(shù)的函數(shù)地址,也就是f返回的那個函數(shù)。

小結(jié)

  1. Go語言支持閉包
  2. Go語言能通過escape analyze識別出變量的作用域,自動將變量在堆上分配。將閉包環(huán)境變量在堆上分配是Go實現(xiàn)閉包的基礎(chǔ)。
  3. 返回閉包時并不是單純返回一個函數(shù),而是返回了一個結(jié)構(gòu)體,記錄下函數(shù)返回地址和引用的環(huán)境中的變量地址。

轉(zhuǎn)自:

tiancaiamao.gitbooks.io/go-internals/content/zh/03.6.html

編輯:jq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7631

    瀏覽量

    141208
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4379

    瀏覽量

    64651
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4895

    瀏覽量

    70543
  • go語言
    +關(guān)注

    關(guān)注

    1

    文章

    159

    瀏覽量

    9349

原文標(biāo)題:Golang 閉包的實現(xiàn)

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    Windows環(huán)境下32位匯編語言中文資料

    電子發(fā)燒友網(wǎng)站提供《Windows環(huán)境下32位匯編語言中文資料.rar》資料免費下載
    發(fā)表于 06-30 15:14 ?0次下載

    深入理解C語言:C語言循環(huán)控制

    改變程序的執(zhí)行流程,使代碼更加靈活和可控。本文將詳細(xì)介紹這些語句的作用及其應(yīng)用場景,并通過示例代碼進(jìn)行說明。Part.1break語句C語言中break語句有兩種
    的頭像 發(fā)表于 04-29 18:49 ?1062次閱讀
    深入理解C<b class='flag-5'>語言</b>:C<b class='flag-5'>語言</b>循環(huán)控制

    接觸器常開常是什么意思

    在電氣自動化控制系統(tǒng)中,接觸器作為一種重要的控制元件,廣泛應(yīng)用于電動機啟動、停止控制,以及電力線路的切換和保護。接觸器的常開和常觸點是其核心組成部分,對于實現(xiàn)電路的邏輯控制和保護起著至關(guān)重要的作用
    的頭像 發(fā)表于 02-06 16:21 ?2474次閱讀

    EE-62:在C語言中訪問短字內(nèi)存

    電子發(fā)燒友網(wǎng)站提供《EE-62:在C語言中訪問短字內(nèi)存.pdf》資料免費下載
    發(fā)表于 01-07 14:02 ?0次下載
    EE-62:在C<b class='flag-5'>語言中</b>訪問短字內(nèi)存

    EE-128:C語言中的DSP:從C調(diào)用匯編類成員函數(shù)

    電子發(fā)燒友網(wǎng)站提供《EE-128:C語言中的DSP:從C調(diào)用匯編類成員函數(shù).pdf》資料免費下載
    發(fā)表于 01-07 13:48 ?0次下載
    EE-128:C<b class='flag-5'>語言中</b>的DSP:從C調(diào)用匯編類成員函數(shù)

    深入理解C語言:循環(huán)語句的應(yīng)用與優(yōu)化技巧

    能讓你的代碼更加簡潔明了,還能顯著提升程序執(zhí)行效率。本文將詳細(xì)介紹C語言中的三種常見循環(huán)結(jié)構(gòu)——while循環(huán)、for循環(huán)和do...while循環(huán),帶你深入理解它
    的頭像 發(fā)表于 12-07 01:11 ?609次閱讀
    深入理解C<b class='flag-5'>語言</b>:循環(huán)語句的應(yīng)用與優(yōu)化技巧

    C語言中申請的堆內(nèi)存能不能自動釋放

    C語言中申請的堆內(nèi)存能不能自動釋放?每次都要手動 free 太麻煩,也容易忘記。 學(xué)過 C++ 的同學(xué),應(yīng)該首先能想到智能指針。 但是這是C語言,沒有類和對象、構(gòu)造析構(gòu)這些技術(shù),想要自動釋放很難
    的頭像 發(fā)表于 11-27 09:33 ?502次閱讀

    在學(xué)習(xí)go語言的過程踩過的坑

    作為一個5年的phper,這兩年公司和個人都在順應(yīng)技術(shù)趨勢,新項目慢慢從php轉(zhuǎn)向了go語言,從2021年到現(xiàn)在,筆者手上也先后開發(fā)了兩個go項目。在學(xué)習(xí)go
    的頭像 發(fā)表于 11-11 09:22 ?442次閱讀

    C語言中的socket編程基礎(chǔ)

    Socket編程簡介 Socket是一種通信機制,允許程序之間進(jìn)行通信。在C語言中,socket編程是網(wǎng)絡(luò)編程的基礎(chǔ)。通過使用socket,程序可以發(fā)送和接收數(shù)據(jù),實現(xiàn)不同計算機之間的通信
    的頭像 發(fā)表于 11-01 16:51 ?1165次閱讀

    go語言如何解決并發(fā)問題

    作為一個后端開發(fā),日常工作中接觸最多的兩門語言就是PHP和GO了。無可否認(rèn),PHP確實是最好的語言(手動狗頭哈哈),寫起來真的很舒爽,沒有任何心智負(fù)擔(dān),字符串和整型壓根就不用區(qū)分,開發(fā)速度真的是比
    的頭像 發(fā)表于 10-23 13:38 ?474次閱讀
    <b class='flag-5'>go</b><b class='flag-5'>語言</b>如何解決并發(fā)問題

    c語言中從左到右結(jié)合怎么看

    在C語言中,操作符的結(jié)合性(Associativity)是指當(dāng)操作符在表達(dá)式中連續(xù)出現(xiàn)時,它們?nèi)绾闻c操作數(shù)結(jié)合的順序。對于大多數(shù)二元操作符(即需要兩個操作數(shù)的操作符),C語言遵循兩種基本的結(jié)合方式
    的頭像 發(fā)表于 08-20 11:42 ?1613次閱讀

    磁性開關(guān)常與常開型號區(qū)別

    磁性開關(guān)的定義 常型磁性開關(guān)是指在沒有磁場作用時,觸點處于閉合狀態(tài)的磁性開關(guān)。當(dāng)磁場作用于磁簧管時,觸點會斷開,從而實現(xiàn)電路的控制。 常型磁性開關(guān)的工作原理 常型磁性開關(guān)的工作原
    的頭像 發(fā)表于 08-19 10:38 ?3378次閱讀

    三十分鐘入門基礎(chǔ)Go Java小子版

    前言 Go語言定義 Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開發(fā)的一種靜態(tài)、強類型、編譯型語言
    的頭像 發(fā)表于 08-12 14:32 ?967次閱讀
    三十分鐘入門基礎(chǔ)<b class='flag-5'>Go</b> Java小子版

    名單公布!【書籍評測活動NO.39】倉頡編程快速上手 | 開發(fā)者的第一個倉頡語言程序

    內(nèi)嵌了 AgentDSL 的編程框架,實現(xiàn)了自然語言與編程語言有機融合。多 Agent 協(xié)同,簡化符號表達(dá),模式可以自由組合,支持各類智能應(yīng)用開發(fā)。 從以上代碼段可以看到,在倉頡語言中
    發(fā)表于 07-24 17:01

    Transformer語言模型簡介與實現(xiàn)過程

    任務(wù),隨后迅速擴展到其他NLP任務(wù)中,如文本生成、語言理解、問答系統(tǒng)等。本文將詳細(xì)介紹Transformer語言模型的原理、特點、優(yōu)勢以及實現(xiàn)
    的頭像 發(fā)表于 07-10 11:48 ?2937次閱讀
    主站蜘蛛池模板: 日本三级理论 | 日韩dv| 日韩a毛片免费全部播放完整 | 国产大毛片 | 四虎影视永久地址 | 天天操天天搞 | 天天曰天天爽 | 欧美一级特黄啪啪片免费看 | 一区二区三区在线看 | 天天摸天天做天天爽天天弄 | 久久精品在 | 网红和老师啪啪对白清晰 | 在线女同免费观看网站 | 欧美日韩一卡2卡三卡4卡新区 | 日本免费观看完整视频 | 99精品视频在线播放2 | 能看的黄色网址 | 国产亚洲人成a在线v网站 | 久久男人的天堂色偷偷 | 国产亚洲午夜精品a一区二区 | 女人大毛片一级毛片一 | 黑人xxxx精品 | 国产三级精品最新在线 | 精品女同 | 91桃色国产线观看免费 | 性色aⅴ闺蜜一区二区三区 性色成人网 | 性free中国美女hd | 五月天婷婷一区二区三区久久 | 三级视频在线播放线观看 | 国产在线播放一区 | 九九热九九 | 欧美精品成人a多人在线观看 | 欧美黄色大片免费观看 | 久久国产影视 | 好黄好猛好爽好痛的视频 | 欧美大黄 | 亚洲深夜在线 | 日本一区二区不卡在线 | 大尺度在线 | 手机看片精品国产福利盒子 | 五月天婷婷爱 |