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

Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實例詳解

 更新時間:2023年10月19日 10:49:04   作者:帽兒山的槍手  
這篇文章主要為大家介紹了Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

匿名函數(shù)

在Go語言中,函數(shù)可以像普通變量一樣被傳遞或使用,支持隨時在代碼里定義匿名函數(shù)。

匿名函數(shù)由一個不帶函數(shù)名的函數(shù)聲明和函數(shù)體組成。匿名函數(shù)的優(yōu)越性在于可以直接使用函數(shù)內(nèi)的變量,不必申明。

匿名函數(shù)有動態(tài)創(chuàng)建的特性,該特性使得匿名函數(shù)不用通過參數(shù)傳遞的方式,就可以直接引用外部的變量。

使用

第一種用法:將匿名函數(shù)賦給變量,在通過變量調(diào)用匿名函數(shù)

sum := func(a, b int) int {
  return a + b
}
fmt.Println(sum(1, 2)) // 輸出 3

第二種用法:在定義匿名函數(shù)的時候直接使用,這種方式只能使用一次傳參

sum := func(a, b int) int {
    return a + b
}(1,2) // 傳入?yún)?shù)
fmt.Println(sum) // 輸出 3

第三種用法:將匿名函數(shù)賦給一個全局變量,匿名函數(shù)在當(dāng)前程序中都可以使用

package main
import "fmt"
var (
  // 全局變量必須首字母大寫
    Sum = func(a, b int) int {
        return a + b
    }
)
func main() {
    sum := Sum(1, 2)
    fmt.Println("sum=", sum) // 輸出 sum= 3
}

閉包

所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環(huán)境的表達式(通常是一個函數(shù)),因而這些變量也是該表達式的一部分。

閉包(Closure),是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。閉包在運行時可以有多個實例,不同的引用環(huán)境和相同的函數(shù)組合可以產(chǎn)生不同的實例。

可以理解為:閉包是匿名函數(shù)與匿名函數(shù)所引用環(huán)境的組合,類似常規(guī)函數(shù)引用全局變量處于一個包的環(huán)境。

閉包的優(yōu)點

  • 變量可以常駐內(nèi)存
  • 變量不污染全局

閉包里作用域返回的局部變量不會被立刻銷毀回收,可能會占用更多內(nèi)存過度使用閉包會導(dǎo)致性能下降。

使用

package main
import "fmt"
func main() {
    n := 0
    count := func() int {  // 這就是一個閉包
        n += 1
        return n
    }
    fmt.Println(count()) // 輸出 1
    fmt.Println(count()) // 輸出 2
}

常規(guī)函數(shù)、匿名函數(shù) + 全局變量 + 包就等同于閉包, count不僅存儲了函數(shù)的返回值,還存儲了閉包的狀態(tài)。

閉包被返回賦予一個同類型的變量時,同時賦值的是整個閉包的狀態(tài),該狀態(tài)會一直存在外部被賦值的變量count中,直到count被銷毀,整個閉包生命周期結(jié)束。

也可以寫成下列形式

package main
import "fmt"
func Count() func() int { // 返回函數(shù)
    n := 0
    return func() int {
        n++
        return n
    }
}
func main() {
    count := Count()
    fmt.Println(count()) // 輸出 1
    fmt.Println(count()) // 輸出 2
}

高級閉包特性,比如并發(fā)中的閉包。 將放到后面章節(jié)為大家介紹。

遞歸函數(shù)

遞歸,就是在運行的過程中調(diào)用自己。

一個函數(shù)調(diào)用自己, 就叫做遞歸函數(shù)。

構(gòu)成遞歸具備的條件:

  • 子問題需要與原始問題為同樣的事,且更為簡單。
  • 不能無限制地調(diào)用本身,須有個出口,化簡為非遞歸狀況處理。

使用

舉例:數(shù)字階乘

一個正整數(shù)的階乘是所有小于及等于該數(shù)的正整數(shù)的積,并且0的階乘為1。

package main
import "fmt"
func factorial(i int) int {  // 解讀為 5*4*3*2*1=120 
    if i <= 1 {
        return 1
    }
    return i * factorial(i-1)
}
func main() {
    var i int = 5
    fmt.Printf("%d\n", factorial((i))) // 120
}
1808年,基斯頓·卡曼引進這個表示法。

舉例:裴波那契數(shù)列(Fibonacci)

這個數(shù)列從第3項開始,每一項都等于前兩項之和。

package main
import "fmt"
func fibonaci(i int) int {    
    if i == 0 {
        return 0    
    }
    if i == 1 {
        return 1
    }    
    return fibonaci(i-1) + fibonaci(i-2)
}
func main() {
    var i int
    for i = 0; i < 10; i++ {
        fmt.Printf("%d ", fibonaci(i)) // 0 1 1 2 3 5 8 13 21 34
    }
}

延遲調(diào)用 (defer)

在基礎(chǔ)語法中已經(jīng)介紹了defer延遲調(diào)用的使用,今天深入了解使用一下defer機制。

defer特性

  • 關(guān)鍵字 defer 用于注冊延遲調(diào)用。
  • 這些調(diào)用直到 return 前才被執(zhí)。因此,可以用來做資源清理。
  • 多個defer語句,按先進后出的方式執(zhí)行。
  • defer語句中的變量,在defer聲明時就決定了。
  • 某個延遲調(diào)用發(fā)生錯誤,這些調(diào)用依舊會被執(zhí)行。

defer后面的語句在執(zhí)行的時候,函數(shù)調(diào)用的參數(shù)會被保存起來,但是不執(zhí)行。也就是復(fù)制了一份。

defer用途

  • 關(guān)閉文件句柄
  • 鎖資源釋放
  • 數(shù)據(jù)庫連接釋放

使用

多個 defer 注冊,按 FILO 次序執(zhí)行 ( 先進后出 ) 原則。

package main
func main() {
    defer println("1") // 先進來, 最后出去
    defer println("2")
    defer println("3") // 最后進來, 先出去
}

輸出

3
2
1

延遲調(diào)用參數(shù)在注冊時求值或復(fù)制,可以用指針或閉包 “延遲” 讀取。

package main

import "fmt"

func main() {
    x, y := 10, 100
    defer func(i int) {
        fmt.Printf("defer x = %v, y = %v\n", i, y) // y 閉包引用
    }(x) // x 被復(fù)制

    x += 10
    y += 20
    println("x = ", x, "y = ", y)
}

輸出

x =  20 y =  120
defer x = 10, y = 120

defer和return兩者執(zhí)行順序

  • 有名返回值 (函數(shù)返回值為已經(jīng)命名的返回值)
package main
import "fmt"
func foo() (i int) { // 3.return i 值
    i = 0
    defer func() {
    fmt.Println(i) // 2.讀取臨時變量地址(返回值)
    }()
    return 2 // 1.返回值賦值,寫入臨時變量
}
func main() {
    foo()
}

輸出

2

在 foo() 返回值的函數(shù)中 (這里返回值為 i),執(zhí)行 return 2 的時候?qū)嶋H上已經(jīng)將i 的值重新賦值為2。 所以defer closure輸出結(jié)果為2。

解析:

return 的機制:1.首先將返回值放到一個臨時變量中(為返回值賦值) 2. 然后將返回值返回到被調(diào)用處。

而defer函數(shù)恰在return的兩個操作之間執(zhí)行。

執(zhí)行順序是: 先為返回值賦值,即將返回值放到一個臨時變量中,然后執(zhí)行defer,然后return到函數(shù)被調(diào)用處。

  • 無名返回值 (即函數(shù)返回值為沒有命名的函數(shù)返回值)
package main
import "fmt"
func foo() int {
    var i int
    defer func() {
        i++ // 這個地方 i,不是臨時變量
        fmt.Println("defer = ", i) // 輸出 defer = 1
    }()
    return i // 返回值賦值,寫入臨時變量
}
func main() {
    fmt.Println("return = ", foo()) // 輸出 return = 0
}

 解析:return 先把返回值放到一個臨時變量中,defer函數(shù)無法獲取到這個臨時變量地址 (沒有函數(shù)返回值),所以無論defer函數(shù)做任何操作,都不會對最終返回值造成任何變動。

以上就是Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實例詳解的詳細內(nèi)容,更多關(guān)于Golang 匿名遞歸函數(shù)閉包的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang 編譯成DLL文件的操作

    Golang 編譯成DLL文件的操作

    這篇文章主要介紹了Golang 編譯成DLL文件的操作方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Golang Gin框架實現(xiàn)文件下載功能的示例代碼

    Golang Gin框架實現(xiàn)文件下載功能的示例代碼

    本文主要介紹了Golang Gin框架實現(xiàn)文件下載功能的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 如何讓shell終端和goland控制臺輸出彩色的文字

    如何讓shell終端和goland控制臺輸出彩色的文字

    這篇文章主要介紹了如何讓shell終端和goland控制臺輸出彩色的文字的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go實現(xiàn)整合Logrus實現(xiàn)日志打印

    Go實現(xiàn)整合Logrus實現(xiàn)日志打印

    這篇文章主要介紹了Go實現(xiàn)整合Logrus實現(xiàn)日志打印,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • go 指針接收者和值接收者的區(qū)別小結(jié)

    go 指針接收者和值接收者的區(qū)別小結(jié)

    在Go 語言中,值接收者和指針接收者是方法定義中的兩種接收者類型,本文主要介紹了go 指針接收者和值接收者的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Golang中tinyrpc框架的源碼解讀詳解

    Golang中tinyrpc框架的源碼解讀詳解

    tinyrpc是一個高性能的基于protocol?buffer的rpc框架。項目代碼非常少,很適合初學(xué)者進行g(shù)olang的學(xué)習(xí)。本文將從源碼的角度帶大家了解tinyrpc框架的使用,需要的可以參考一下
    2023-01-01
  • 淺談Go語言中的結(jié)構(gòu)體struct & 接口Interface & 反射

    淺談Go語言中的結(jié)構(gòu)體struct & 接口Interface & 反射

    下面小編就為大家?guī)硪黄獪\談Go語言中的結(jié)構(gòu)體struct & 接口Interface & 反射。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • go語言之給定英語文章統(tǒng)計單詞數(shù)量(go語言小練習(xí))

    go語言之給定英語文章統(tǒng)計單詞數(shù)量(go語言小練習(xí))

    這篇文章給大家分享go語言小練習(xí)給定英語文章統(tǒng)計單詞數(shù)量,實現(xiàn)思路大概是利用go語言的map類型,以每個單詞作為關(guān)鍵字存儲數(shù)量信息,本文通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2020-01-01
  • GO中cannot find module的錯誤解決

    GO中cannot find module的錯誤解決

    本文主要介紹了GO中cannot find module的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • Golang利用WebSocket實現(xiàn)實時推送功能

    Golang利用WebSocket實現(xiàn)實時推送功能

    WebSocket 是一個實時雙向通信的協(xié)議,底層用 TCP,借用 HTTP 建立連接,專門用來做實時功能,下面小編就和大家詳細介紹一下Golang如何利用WebSocket實現(xiàn)實時推送功能吧
    2026-03-03

最新評論

施甸县| 湖口县| 桃江县| 通江县| 汝城县| 彰武县| 苗栗县| 濮阳市| 新绛县| 涟源市| 柳河县| 营山县| 闻喜县| 沾化县| 华池县| 海门市| 赤壁市| 营口市| 随州市| 丽江市| 元氏县| 莲花县| 香格里拉县| 星座| 兴安县| 军事| 鄂尔多斯市| 望谟县| 蒲城县| 镇安县| 饶阳县| 平定县| 明星| 石景山区| 富平县| 麻江县| 喜德县| 海丰县| 临颍县| 桐乡市| 长治县|