最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解Go語言中的閉包

 更新時(shí)間:2017年03月21日 08:21:42   投稿:daisy  
Go函數(shù)是可以閉包的。閉包是一個(gè)函數(shù)值,他來自函數(shù)體外部的變量引用。 下面這篇文章通過一個(gè)demo來進(jìn)行深入的介紹了Go語言中閉包的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考下。

閉包

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

Go語言中的閉包

先看一個(gè)demo:

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

函數(shù)f返回了一個(gè)函數(shù),返回的這個(gè)函數(shù)就是一個(gè)閉包。這個(gè)函數(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++時(shí)修改的不是同一個(gè)i,因此兩次的輸出都是1。函數(shù)f每進(jìn)入一次,就形成了一個(gè)新的環(huán)境,對應(yīng)的閉包中,函數(shù)都是同一個(gè)函數(shù),環(huán)境卻是引用不同的環(huán)境。

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

escape analyze

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

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

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

為了驗(yàn)證這一點(diǎn),可以觀察函數(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ù)實(shí)現(xiàn)的。

如果輸入命令:

go build --gcflags=-m main.go

可以看到輸出:

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

總結(jié)

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

相關(guān)文章

  • go中的protobuf和grpc使用教程

    go中的protobuf和grpc使用教程

    gRPC 是 Google 公司基于 Protobuf 開發(fā)的跨語言的開源 RPC 框架,這篇文章主要介紹了go中的protobuf和grpc使用教程,需要的朋友可以參考下
    2024-08-08
  • Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用教程

    Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用教程

    輸入輸出在任何一門語言中都必須提供的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Go語言實(shí)現(xiàn)多協(xié)程文件下載器的過程詳解

    Go語言實(shí)現(xiàn)多協(xié)程文件下載器的過程詳解

    這篇文章主要介紹了Go語言實(shí)現(xiàn)多協(xié)程文件下載器的相關(guān)資料,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-08-08
  • Go語言利用net/mail包解析郵件地址與消息格式

    Go語言利用net/mail包解析郵件地址與消息格式

    Go 的 net/mail 包提供了符合 RFC 5322 標(biāo)準(zhǔn)的郵件解析能力,讓你輕松處理郵件相關(guān)的各種場景,下面就跟隨小編一起來深入了解下具體實(shí)現(xiàn)吧
    2025-08-08
  • go-kit組件使用hystrix中間件的操作

    go-kit組件使用hystrix中間件的操作

    這篇文章主要介紹了go-kit組件使用hystrix中間件的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • go for range遍歷二維數(shù)組的示例

    go for range遍歷二維數(shù)組的示例

    今天小編就為大家分享一篇關(guān)于go for range遍歷二維數(shù)組的示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • go語言中的log 包示例詳解

    go語言中的log 包示例詳解

    Go語言的log包提供了用于記錄日志的基本功能,相比fmt包,增加了時(shí)間戳、日志級別等日志管理功能,非常適合用于調(diào)試和記錄運(yùn)行信息,本文呢介紹go語言中的log 包,感興趣的朋友一起看看吧
    2024-11-11
  • Go語言學(xué)習(xí)教程之goroutine和通道的示例詳解

    Go語言學(xué)習(xí)教程之goroutine和通道的示例詳解

    這篇文章主要通過A?Tour?of?Go中的例子進(jìn)行學(xué)習(xí),以此了解Go語言中的goroutine和通道,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-09-09
  • Go語言七篇入門教程二程序結(jié)構(gòu)與數(shù)據(jù)類型

    Go語言七篇入門教程二程序結(jié)構(gòu)與數(shù)據(jù)類型

    這篇文章主要為大家介紹了Go語言的程序結(jié)構(gòu)與數(shù)據(jù)類型,本篇文章是Go語言七篇入門系列文,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • Go語言有狀態(tài)goroutine的具體使用

    Go語言有狀態(tài)goroutine的具體使用

    Go語言中的有狀態(tài)goroutine提供了一種基于通信的并發(fā)狀態(tài)管理范式,通過將狀態(tài)的讀寫權(quán)限封裝在單個(gè)goroutine中,避免傳統(tǒng)互斥鎖的競爭問題,感興趣的可以了解一下
    2025-07-07

最新評論

永康市| 禹州市| 安宁市| 时尚| 青浦区| 辉县市| 桐柏县| 商丘市| 怀化市| 肥东县| 鞍山市| 景谷| 区。| 措美县| 沂南县| 界首市| 化隆| 潜江市| 都昌县| 满洲里市| 浮山县| 乐至县| 星子县| 昌黎县| 鹿邑县| 伊春市| 平武县| 武清区| 京山县| 正宁县| 建始县| 大方县| 屯留县| 建瓯市| 贡觉县| 溧阳市| 华坪县| 育儿| 姜堰市| 张家界市| 行唐县|