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