3 回答
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())
}
}
TA貢獻1794條經驗 獲得超8個贊
1)為什么我不重置?
Go 中的閉包通過引用捕獲變量。這意味著內部函數持有i對外部作用域中變量的引用,并且每次調用它都會訪問同一個變量。
2) 是 nextEven() 返回并返回 uint 還是 Println 如此聰明以至于它可以處理所有事情?
fmt.Println()(沿fmt.Print(),fmt.Fprint()等等)可以工作大多數類型。它以“默認格式”打印其參數。這與fmt.Printf()使用%v動詞打印的內容相同。
- 3 回答
- 0 關注
- 281 瀏覽
添加回答
舉報
