gpt4 book ai didi

Go闭包变量作用域

转载 作者:IT王子 更新时间:2023-10-29 01:07:16 24 4
gpt4 key购买 nike

我正在阅读“CreateSpace Go 2012 编程简介”

在第 86 页我发现了这个邪恶的魔法

func makeEvenGenerator() func() uint {
i := uint(0)

return func() (ret uint) {
ret = i
i += 2
return
}
}

// here's how it's called
nextEven := makeEvenGenerator()
fmt.Println(nextEven())
fmt.Println(nextEven())
fmt.Println(nextEven())

1) 为什么 i 没有重置?2) nextEven() 返回和 uint 还是 Println 如此聪明以至于它可以处理所有事情?

最佳答案

为了清楚起见,我将为这两个函数指定名称:

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 中的一等公民,即它们可以是右 watch 达式,例如:

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

f() // prints "f was called"

在您的代码中,闭包覆盖了工厂的上下文,这称为词法作用域。这就是为什么变量 i 在闭包内可用,不是作为副本而是作为对 i 本身的引用。

闭包使用一个名为 ret命名返回值。这意味着在闭包内你将隐式声明 ret 并且在 return 点,无论 ret 有什么值都将被返回.

这一行:

ret = i

会将i的当前值赋给ret。它不会改变i。然而,这一行:

i += 2

将在下次调用闭包时更改 i 的值。


Here你会发现我为你一起写的一个小闭包例子。它不是很有用,但在我看来很好地说明了闭包的范围、目的和用途:

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())
}

}

关于Go闭包变量作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19957323/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com