Go 直接调用函数和使用指针的行为不同

Go 直接调用函数和使用指针的行为不同,go,Go,我是新手,对下面的代码感到困惑 package main import "fmt" // fibonacci is a function that returns // a function that returns an int. func fibonacci() func() int { previous := 0 current := 1 return func () int{ current = current+previous

我是新手,对下面的代码感到困惑

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    previous := 0
    current := 1
    return func () int{
        current = current+previous
        previous = current-previous
        return current

    }
}

func main() {
    f := fibonacci
    for i := 0; i < 10; i++ {
        fmt.Println(f()())
    }
}
主程序包
输入“fmt”
//斐波那契函数是一个返回
//返回整数的函数。
func fibonacci()func()int{
上一个:=0
电流:=1
返回func()int{
当前=当前+上一个
上一个=当前上一个
回流
}
}
func main(){
f:=斐波那契
对于i:=0;i<10;i++{
fmt.Println(f()())
}
}
这段代码应该打印出斐波那契序列(前10个),但只打印出10乘以1。 但如果我将代码更改为:

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}
func main(){
f:=fibonacci()
对于i:=0;i<10;i++{
fmt.Println(f())
}
}
那么它工作得很好。输出是斐波那契序列

谁能帮我解释一下吗

谢谢

fibonacci()
创建了一个新的fibonacci生成器函数
fibonacci()()
执行相同的操作,然后调用它一次,返回结果并丢弃生成器,不再使用。如果您在循环中调用它,它将继续创建新的生成器,并且只使用它们的第一个值


如果您想要的不仅仅是第一个值,那么您需要完全按照您在第二个示例中所做的操作。将生成器本身存储在一个变量中,然后多次调用同一个生成器。

这与返回闭包后如何将变量封装在闭包中有关。 考虑下面的例子():

运行此代码将产生如下输出。我注释 哪一行来自哪一条语句:

newClosure with &i= 0xc010000000    // a := newClosure()
0 0xc010000000                      // a()
1 0xc010000000                      // a()
2 0xc010000000                      // a()
newClosure with &i= 0xc010000008    // b := newClosure()
0 0xc010000008                      // b()
3 0xc010000000                      // a()
在本例中,
newClosure
返回的闭包封装了局部变量
i
。 这对应于代码中的
current
等。您可以看到
a
b
具有不同的
i
实例,否则调用
b()
将打印
3
。 您还可以看到
i
变量有不同的地址。(该变量已存在。) 在heap as go上没有单独的堆栈内存,因此在闭包中使用它是非常困难的 没问题。)

因此,通过生成新闭包,您将自动为 闭包和局部变量不在闭包之间共享。这就是原因 为什么在循环中创建一个新的闭包不能让您走得更远

在本例中,代码的等效项为:

for i:=0; i < 10; i++ {
    newClosure()()
}
i:=0的
;i<10;i++{
newClosure()()
}
您已经从输出中看到这将不起作用。

func fibonacci()func()int返回一个(闭包),该闭包返回表示列表中最后生成的数字的
int

第一个main()方法

f := fibonacci
    for i := 0; i < 10; i++ {
        fmt.Println(f()())
    }
f
是具有初始环境的闭包(而不是生成器)(
previous:=0
current
:=1),循环中的每个迭代调用
f()
开关返回
current
并修改环境,因此下一次调用在哪里,
以前的
将是
1
当前的
2

f := fibonacci
    for i := 0; i < 10; i++ {
        fmt.Println(f()())
    }
func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}