日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Go語言中的閉包:封裝數據與功能的強大工具

來源: 責編: 時間:2023-11-01 17:04:27 293觀看
導讀閉包是包括 Go 在內的編程語言的一項強大功能。通過閉包,您可以在函數中封裝數據,并通過函數的返回值訪問這些數據。在本文中,我們將介紹 Go 中閉包的基礎知識,包括它們是什么、如何工作以及如何有效地使用它們。什么是閉

閉包是包括 Go 在內的編程語言的一項強大功能。通過閉包,您可以在函數中封裝數據,并通過函數的返回值訪問這些數據。在本文中,我們將介紹 Go 中閉包的基礎知識,包括它們是什么、如何工作以及如何有效地使用它們。U9y28資訊網——每日最新資訊28at.com

什么是閉包?

go官方有一句解釋:U9y28資訊網——每日最新資訊28at.com

Function literals are closures: they may refer to variables defined in a surrounding function. Those variables are then shared between the surrounding function and the function literal, and they survive as long as they are accessible.U9y28資訊網——每日最新資訊28at.com

翻譯過來就是:U9y28資訊網——每日最新資訊28at.com

函數字面量(匿名函數)是閉包:它們可以引用在周圍函數中定義的變量。然后,這些變量在周圍的函數和函數字面量之間共享,只要它們還可以訪問,它們就會繼續存在。U9y28資訊網——每日最新資訊28at.com

閉包是一種創建函數的方法,這些函數可以訪問在其主體之外定義的變量。閉包是一個可以捕捉其周圍環境狀態的函數。這意味著函數可以訪問不在其參數列表中或在其主體中定義的變量。閉包函數可以在外部函數返回后訪問這些變量。U9y28資訊網——每日最新資訊28at.com

在 Go 中創建閉包

在 Go 中,您可以使用匿名函數創建閉包。創建閉包時,函數會捕獲其周圍環境的狀態,包括外部函數中定義的任何變量。閉包函數可以在外部函數返回后訪問這些變量。U9y28資訊網——每日最新資訊28at.com

下面是一個在 Go 中創建閉包的示例:U9y28資訊網——每日最新資訊28at.com

func adder() func(int) int { // 外部函數 sum := 0 return func(x int) int { // 內部函數  fmt.Println("func sum: ", sum)  sum += x  return sum }}func main() { a := adder() fmt.Println(a(1)) fmt.Println(a(2)) fmt.Println(a(3))}

在本例中,我們定義了一個返回匿名函數的加法器函數。匿名函數捕捉加法器函數中定義的 sum 變量的狀態。每次調用匿名函數時,它都會將參數加到求和變量中,并返回結果。U9y28資訊網——每日最新資訊28at.com

所以其輸出結果為:U9y28資訊網——每日最新資訊28at.com

func sum:  01func sum:  13func sum:  36

在 Go 中使用閉包

在 Go 中,閉包可用于多種用途,包括用函數封裝數據、創建生成器、迭代器和 memoization 函數。U9y28資訊網——每日最新資訊28at.com

下面是一個使用閉包將數據與函數封裝在一起的示例:U9y28資訊網——每日最新資訊28at.com

func makeGreeter(greeting string) func(string) string { return func(name string) string {  fmt.Printf("func greeting: %s, name: %s/n", greeting, name)  return greeting + ", " + name }}func main() { englishGreeter := makeGreeter("Hello") spanishGreeter := makeGreeter("Hola") fmt.Println(englishGreeter("John")) fmt.Println(englishGreeter("Tim")) fmt.Println(spanishGreeter("Juan")) fmt.Println(spanishGreeter("Taylor"))}

在本例中,我們定義了一個名為 makeGreeter 的函數,它返回一個匿名函數。該匿名函數接收一個字符串參數,并返回一個將問候語和名稱連接起來的字符串。我們創建了兩個問候語程序,一個用于英語,一個用于西班牙語,然后用不同的名稱調用它們。U9y28資訊網——每日最新資訊28at.com

所以其輸出為:U9y28資訊網——每日最新資訊28at.com

func greeting: Hello, name: JohnHello, Johnfunc greeting: Hello, name: TimHello, Timfunc greeting: Hola, name: JuanHola, Juanfunc greeting: Hola, name: TaylorHola, Taylor

替換捕獲的變量

Go 閉包的強大功能之一是能夠更改捕獲的變量。這使得代碼中的行為更加靈活和動態。下面是一個例子:U9y28資訊網——每日最新資訊28at.com

func makeCounter() func() int { i := 0 return func() int {  fmt.Println("func i: ", i)  i++  return i }}func main() { counter := makeCounter() fmt.Println(counter()) fmt.Println(counter()) fmt.Println(counter())}

在本例中,makeCounter 函數返回一個閉包,每次調用都會使計數器遞增。i 變量被閉包捕獲,并可被修改以更新計數器。U9y28資訊網——每日最新資訊28at.com

所以其輸出為:U9y28資訊網——每日最新資訊28at.com

func i:  01func i:  12func i:  23

逃逸變量

Go 閉包的另一個高級概念是變量逃逸分析。在 Go 中,變量通常在堆棧上分配,并在超出作用域時被去分配。然而,當變量被閉包捕獲時,它必須在堆上分配,以確保在函數返回后可以訪問它。這會導致性能開銷,因此了解變量何時以及如何逃逸非常重要。U9y28資訊網——每日最新資訊28at.com

我們對比一下兩個方法:U9y28資訊網——每日最新資訊28at.com

func makeAdder1(x1 int) func(int) int { return func(y1 int) int {  return x1 + y1 }}func makeAdder2(x2 int) func(int) int { fmt.Println(x2) return func(y2 int) int {  return x2 + y2 }}func main() { a := makeAdder1(5) fmt.Println(a(1)) b := makeAdder2(6) fmt.Println(b(1))}

makeAdder1 和 makeAdder2 的區別在于函數內的 x 是否被使用。U9y28資訊網——每日最新資訊28at.com

而我們通過逃逸分析:U9y28資訊網——每日最新資訊28at.com

go build -gcflags "-m" main.go

會得到以下輸出:U9y28資訊網——每日最新資訊28at.com

./main.go:5:6: can inline makeAdder1./main.go:6:9: can inline makeAdder1.func1./main.go:13:9: can inline makeAdder2.func1./main.go:12:13: inlining call to fmt.Println./main.go:19:17: inlining call to makeAdder1./main.go:6:9: can inline main.makeAdder1.func1./main.go:20:15: inlining call to main.makeAdder1.func1./main.go:20:13: inlining call to fmt.Println./main.go:23:13: inlining call to fmt.Println./main.go:6:9: func literal escapes to heap./main.go:12:13: ... argument does not escape./main.go:12:14: x2 escapes to heap./main.go:13:9: func literal escapes to heap./main.go:19:17: func literal does not escape./main.go:20:13: ... argument does not escape./main.go:20:15: ~R0 escapes to heap./main.go:23:13: ... argument does not escape./main.go:23:15: b(1) escapes to heap

從逃逸分析結果來看,x 變量被閉包捕獲,必須在堆上分配。不過,如果 x 變量不被閉包之外的任何其他代碼使用,編譯器可以進行優化,將其分配到棧中。U9y28資訊網——每日最新資訊28at.com

共享閉包

最后,Go 中的閉包可以在多個函數之間共享,從而實現更高的靈活性和模塊化代碼。下面是一個例子:U9y28資訊網——每日最新資訊28at.com

type Calculator struct { add func(int, int) int}func NewCalculator() *Calculator { c := &Calculator{} c.add = func(x, y int) int {  fmt.Printf("func x: %d, y: %d/n", x, y)  return x + y } return c}func (c *Calculator) Add(x, y int) int { return c.add(x, y)}func main() { calc := NewCalculator() fmt.Println(calc.Add(1, 2)) fmt.Println(calc.Add(2, 3))}

在本例中,Calculator 結構具有一個 add 函數,該函數在 NewCalculator 函數中通過閉包進行了初始化。Calculator 結構的 Add 方法只需調用 add 函數,這樣就可以在多個上下文中重復使用。U9y28資訊網——每日最新資訊28at.com

所以其輸出為:U9y28資訊網——每日最新資訊28at.com

func x: 1, y: 23func x: 2, y: 35

結論

在 Go 編程中,閉包是一個強大的工具,可用于用函數封裝數據,并創建生成器和迭代器等。它們提供了一種訪問函數體外定義的變量的方法,即使在函數返回后也是如此。U9y28資訊網——每日最新資訊28at.com


U9y28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-16368-0.htmlGo語言中的閉包:封裝數據與功能的強大工具

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Rust編程基礎之六大數據類型

下一篇: 你知道 Python 其實自帶了小型數據庫嗎

標簽:
  • 熱門焦點
  • 鴻蒙OS 4.0公測機型公布:甚至連nova6都支持

    華為全新的HarmonyOS 4.0操作系統將于今天下午正式登場,官方在發布會之前也已經正式給出了可升級的機型產品,這意味著這些機型會率先支持升級享用。這次的HarmonyOS 4.0支持
  • 轎車從天而降電動車主被撞身亡 超速搶道所致:現場視頻讓網友吵翻

    近日,上海青浦區法院判決轎車從天而降電動車主被撞身亡案,轎車車主被判有期徒刑一年。案件顯示當時男子駕駛轎車在上海某路段行駛,前車忽然轉彎提速超車,
  • K8S | Service服務發現

    一、背景在微服務架構中,這里以開發環境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網關、注冊中心、配置中心等相關服務,可以被集群外部訪問;圖片對于測試「Tes」環境或者
  • 三言兩語說透設計模式的藝術-單例模式

    寫在前面單例模式是一種常用的軟件設計模式,它所創建的對象只有一個實例,且該實例易于被外界訪問。單例對象由于只有一個實例,所以它可以方便地被系統中的其他對象共享,從而減少
  • 讓我們一起聊聊文件的操作

    文件【1】文件是什么?文件是保存數據的地方,是數據源的一種,比如大家經常使用的word文檔、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存數據,它既可以保
  • 只需五步,使用start.spring.io快速入門Spring編程

    步驟1打開https://start.spring.io/,按照屏幕截圖中的內容創建項目,添加 Spring Web 依賴項,并單擊“生成”按鈕下載 .zip 文件,為下一步做準備。請在進入步驟2之前進行解壓。圖
  • 使用LLM插件從命令行訪問Llama 2

    最近的一個大新聞是Meta AI推出了新的開源授權的大型語言模型Llama 2。這是一項非常重要的進展:Llama 2可免費用于研究和商業用途。(幾小時前,swyy發現它已從LLaMA 2更名為Lla
  • JVM優化:實戰OutOfMemoryError異常

    一、Java堆溢出堆內存中主要存放對象、數組等,只要不斷地創建這些對象,并且保證 GC Roots 到對象之間有可達路徑來避免垃 圾收集回收機制清除這些對象,當這些對象所占空間超過
  • 簽約井川里予、何丹彤,單視頻點贊近千萬,MCN黑馬永恒文希快速崛起!

    來源:視聽觀察永恒文希傳媒作為一家MCN公司,說起它的名字來,可能大家會覺得有點兒陌生,但是說出來下面一串的名字之后,或許大家就會感到震驚,原來這么多網紅,都簽約這家公司了。根
Top 主站蜘蛛池模板: 榆树市| 景洪市| 鲁甸县| 永福县| 西乌珠穆沁旗| 怀远县| 胶南市| 土默特右旗| 靖江市| 东辽县| 西宁市| 神木县| 金坛市| 江北区| 玛曲县| 绥棱县| 宜城市| 东乌| 灵川县| 长沙市| 安龙县| 高尔夫| 龙口市| 辉县市| 安多县| 六安市| 五莲县| 兴宁市| 德阳市| 舞钢市| 五大连池市| 依兰县| 永济市| 石柱| 恩平市| 慈溪市| 珠海市| 邯郸市| 余庆县| 崇礼县| 卓尼县|