亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go 閉包變量作用域

Go 閉包變量作用域

Go
慕的地6264312 2021-07-05 13:49:41
我正在閱讀“CreateSpace An Introduction to Programming in Go 2012”在第 86 頁我發現了這個邪惡的魔法func makeEvenGenerator() func() uint {    i := uint(0)    return func() (ret uint) {        ret = i        i += 2        return    }}// here's how it's callednextEven := makeEvenGenerator()fmt.Println(nextEven())fmt.Println(nextEven())fmt.Println(nextEven())1)為什么i不重置?2)正在nextEven()回歸,uint或者Println非常聰明,可以處理所有事情?
查看完整描述

3 回答

?
牧羊人nacy

TA貢獻1862條經驗 獲得超7個贊

為了清楚起見,我將為這兩個函數指定名稱:


func makeEvenGenerator() func() uint { // call this "the factory"

    i := uint(0)


    return func() (ret uint) { // call this "the closure"

        ret = i

        i += 2

        return

    }

}

工廠返回閉包——函數是 Go 中的一等公民,即它們可以是右手表達式,例如:


f := func() { fmt.Println("f was called"); }


f() // prints "f was called"

在您的代碼中,閉包包裝了工廠的上下文,這稱為詞法范圍。這就是為什么變量i在閉包內可用,而不是作為副本,而是作為對i自身的引用。


封閉使用命名返回值叫ret。這意味著在閉包中您將隱式聲明ret并且在 點處return,ret將返回任何值。


這一行:


ret = i

將分配的電流值i來ref。它不會改變i。但是,這一行:


i += 2

將i在下次調用閉包時更改 的值。


在這里你會發現我為你一起寫的一個小閉包例子。它不是非常有用,但在我看來很好地說明了閉包的范圍、目的和使用:


package main


import "fmt"


func makeIterator(s []string) func() func() string {

    i := 0

    return func() func() string {

        if i == len(s) {

            return nil

        }

        j := i

        i++

        return func() string {

            return s[j]

        }

    }

}


func main() {


    i := makeIterator([]string{"hello", "world", "this", "is", "dog"})


    for c := i(); c != nil; c = i() {

        fmt.Println(c())

    }


}


查看完整回答
反對 回復 2021-07-12
?
慕田峪9158850

TA貢獻1794條經驗 獲得超8個贊

1)為什么我不重置?

Go 中的閉包通過引用捕獲變量。這意味著內部函數持有i對外部作用域中變量的引用,并且每次調用它都會訪問同一個變量。

2) 是 nextEven() 返回并返回 uint 還是 Println 如此聰明以至于它可以處理所有事情?

fmt.Println()(沿fmt.Print()fmt.Fprint()等等)可以工作大多數類型。它以“默認格式”打印其參數。這與fmt.Printf()使用%v動詞打印的內容相同。


查看完整回答
反對 回復 2021-07-12
?
繁花不似錦

TA貢獻1851條經驗 獲得超4個贊

閉包中的變量既沒有代碼段也沒有上下文。


查看完整回答
反對 回復 2021-07-12
  • 3 回答
  • 0 關注
  • 281 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號