Go語(yǔ)言func匿名函數(shù)閉包示例詳解
前言
今天繼續(xù)為大家更新Go語(yǔ)言學(xué)習(xí)記錄的文章。
函數(shù)是任何一門(mén)編程語(yǔ)言最重要的組成部分之一。函數(shù)簡(jiǎn)單理解是一段代碼的封裝:把一段邏輯抽象出來(lái)封裝到一個(gè)函數(shù)中,給他取個(gè)名字,每次需要的時(shí)候調(diào)用這個(gè)函數(shù)即可。使用函數(shù)能夠讓代碼更清晰,更簡(jiǎn)潔。
定義
下面的代碼段介紹了go語(yǔ)言中函數(shù)定義的各種情況,以及延遲函數(shù)的使用。
package main import "fmt" // 函數(shù)的定義 func f1(x int, y int) (ret int) { return x + y } // 無(wú)返回值的函數(shù) func f2(x int, y int) { fmt.Println(x + y) } // 沒(méi)有參數(shù)也沒(méi)有返回值的 func f3() { fmt.Println("1111") } // 沒(méi)有參數(shù) 有返回值的 func f4() int { return 4 } // 返回值可以命名也可以不命名 // 命名的返回值就相當(dāng)于在函數(shù)中聲明一個(gè)變量 func f5(x int, y int) (ret int) { ret = x + y //注意:因?yàn)橐呀?jīng)在返回值中聲明了ret,所以這里用= 而不是:= ,避免重復(fù)聲明問(wèn)題 return //因?yàn)橐呀?jīng)在函數(shù)體中聲明了ret,所以在return的時(shí)候不需要重復(fù)聲明 } // 多個(gè)返回值 func f6() (int, int) { return 1, 2 } // 多個(gè)參數(shù)簡(jiǎn)寫(xiě)的方式 // 當(dāng)參數(shù)的類型一致時(shí),可以將連續(xù)的相同參數(shù) 前面參數(shù)的類型省略 比如: func f7(x, y, z int, a, b string, c, d bool) int { return x + y + z } // 可變長(zhǎng)參數(shù) // 可變長(zhǎng)參數(shù)必須放在函數(shù)參數(shù)的最后 func f8(x string, y ...int) { fmt.Println(x) fmt.Println(y) } // defer 延遲執(zhí)行 func deferDemo() { defer fmt.Println("111") //最先defer的語(yǔ)句最后執(zhí)行 defer fmt.Println("222") fmt.Println("333") } // go語(yǔ)言中函數(shù)沒(méi)有默認(rèn)參數(shù)的概念 func main() { r := f5(1, 2) fmt.Println(r) m, n := f6() fmt.Println(m, n) r7 := f7(1, 2, 3, "1", "1", true, false) fmt.Println(r7) f8("hah") //可變長(zhǎng)度 不填也可以 f8("hah", 1, 2, 3, 4) //延遲函數(shù)測(cè)試 deferDemo() }
函數(shù)也可以作為函數(shù)的參數(shù)
舉個(gè)栗子:
package main import "fmt" // 函數(shù)也可以作為函數(shù)參數(shù)的類型 func f3(x func() int) { ret := x() fmt.Printf("f3打印ret的值:%v\n", ret) //2 fmt.Printf("f3打印ret的類型:%T\n", ret) //int } func main() { a := f2 fmt.Printf("a的類型:%T\n", a) f3(a) }
打印結(jié)果:
函數(shù)作為函數(shù)的返回值
package main import "fmt" func f2() int { return 2 } func ff(x, y int) int { return x + y } // 函數(shù)不僅可以作為參數(shù),還可以作為返回值 func f5(x func() int) func(int, int) int { return ff } func main() { f7 := f5(f2) fmt.Printf("f7的值:%v\n",f7) //f7返回的是一個(gè)函數(shù) fmt.Printf("f7的類型:%T\n", f7) }
打印結(jié)果:
小結(jié):
- 我們打印f7的值是一個(gè)內(nèi)存地址
- f7的類型和我們預(yù)期的一致,返回了函數(shù)類型,就是我們定義的ff()函數(shù)
匿名函數(shù)
匿名函數(shù)就是沒(méi)有名字的函數(shù)。匿名函數(shù)多用于實(shí)現(xiàn)回調(diào)函數(shù)和閉包。
在Go語(yǔ)言中函數(shù)內(nèi)部不能再像之前那樣定義函數(shù)了,只能定義匿名函數(shù)。
匿名函數(shù)的定義格式如下:
func(參數(shù))(返回值){ 函數(shù)體 }
匿名函數(shù)因?yàn)闆](méi)有函數(shù)名,所以沒(méi)辦法像普通函數(shù)那樣調(diào)用,所以匿名函數(shù)需要保存到某個(gè)變量或者作為立即執(zhí)行函數(shù):
func main() { // 將匿名函數(shù)保存到變量 add := func(x, y int) { fmt.Println(x + y) } add(10, 20) // 通過(guò)變量調(diào)用匿名函數(shù) //自執(zhí)行函數(shù):匿名函數(shù)定義完加()直接執(zhí)行 func(x, y int) { fmt.Println(x + y) }(10, 20) }
小結(jié):自執(zhí)行函數(shù)就是在匿名函數(shù)后面追加(),表示不需要外部調(diào)用,直接執(zhí)行。
閉包
閉包是一個(gè)函數(shù),這個(gè)函數(shù)包含了他外部作用域的一個(gè)變量
舉個(gè)栗子
package main import "fmt" func adder(x int) func(int) int { return func(y int) int { x += y return x } } func main() { f1 := adder(1) ret := f1(2) fmt.Println(ret) }
打印結(jié)果:
小結(jié): 上面的栗子就是一個(gè)典型的閉包結(jié)構(gòu):匿名函數(shù)內(nèi)部包含了他外部的變量x。
閉包=函數(shù)+引用環(huán)境
總結(jié)
這篇文章我們?cè)敿?xì)介紹了Go語(yǔ)言中函數(shù)的定義、也介紹了匿名函數(shù)和閉包的知識(shí)點(diǎn),更多關(guān)于Go語(yǔ)言func匿名函數(shù)閉包的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語(yǔ)言使用Timeout Context取消任務(wù)的實(shí)現(xiàn)
本文主要介紹了Go語(yǔ)言使用Timeout Context取消任務(wù)的實(shí)現(xiàn),包括基本的任務(wù)取消和控制HTTP客戶端請(qǐng)求的超時(shí),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01Go網(wǎng)絡(luò)編程TCP抓包實(shí)操示例探究
作為一名軟件開(kāi)發(fā)者,網(wǎng)絡(luò)編程是必備知識(shí),本文通過(guò)?Go?語(yǔ)言實(shí)現(xiàn)?TCP?套接字編程,并結(jié)合?tcpdump?工具,展示它的三次握手、數(shù)據(jù)傳輸以及四次揮手的過(guò)程,幫助讀者更好地理解?TCP?協(xié)議與?Go?網(wǎng)絡(luò)編程2024-01-01golang環(huán)形隊(duì)列實(shí)現(xiàn)代碼示例
這篇文章主要介紹了golang環(huán)形隊(duì)列實(shí)現(xiàn)代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11Go語(yǔ)言入門(mén)之基礎(chǔ)語(yǔ)法和常用特性解析
這篇文章主要給大家講解了Go語(yǔ)言的基礎(chǔ)語(yǔ)法和常用特性解析,比較適合入門(mén)小白,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的朋友可以參考下2023-07-07Go結(jié)構(gòu)體指針引發(fā)的值傳遞思考分析
這篇文章主要為大家介紹了Go結(jié)構(gòu)體指針引發(fā)的值傳遞思考分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12Go語(yǔ)言中如何確保Cookie數(shù)據(jù)的安全傳輸
這篇文章主要介紹了Go語(yǔ)言中如何確保Cookie數(shù)據(jù)的安全傳輸,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Go語(yǔ)言函數(shù)的延遲調(diào)用(Deferred Code)詳解
本文將介紹Go語(yǔ)言函數(shù)和方法中的延遲調(diào)用,正如名稱一樣,這部分定義不會(huì)立即執(zhí)行,一般會(huì)在函數(shù)返回前再被調(diào)用,我們通過(guò)一些示例來(lái)了解一下延遲調(diào)用的使用場(chǎng)景2022-07-07Go語(yǔ)言中init函數(shù)特點(diǎn)、用途和注意事項(xiàng)詳解
go語(yǔ)言中有一個(gè)非常神奇的函數(shù)init,它可以在所有程序執(zhí)行開(kāi)始前被執(zhí)行,并且每個(gè)package下面可以存在多個(gè)init函數(shù),這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中init函數(shù)特點(diǎn)、用途和注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2023-07-07