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条经验 获得超7个赞
1)为什么我不重置?
Go 中的闭包通过引用捕获变量。这意味着内部函数持有i
对外部作用域中变量的引用,并且每次调用它都会访问同一个变量。
2) 是 nextEven() 返回并返回 uint 还是 Println 如此聪明以至于它可以处理所有事情?
fmt.Println()
(沿fmt.Print()
,fmt.Fprint()
等等)可以工作大多数类型。它以“默认格式”打印其参数。这与fmt.Printf()
使用%v
动词打印的内容相同。
- 3 回答
- 0 关注
- 222 浏览
添加回答
举报