延迟,return 和 golang 中的参数评估
Defer, return and Argument evaluation in golang
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
a, b := 0, 1
return func() int {
defer func() {a, b = b, a + b}()
return a
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
谁能解释为什么输出从 0, 1, 1, 2, 3, 5 .... 而不是 1, 1, 2, 3, 5, ..... 开始?
据我了解,defer 会在 return 语句之前执行,这意味着 a、b 已更新为 1、1 并且 1 应该被 returned?也许它与表达式被评估或绑定的时间有关,也许 return 已经将 a 绑定为 0,然后在 returning 之前检查是否存在 defer 语句?
go 中的任何内部代码参考都会非常有帮助。
编辑 1:这是我在了解 defer 后尝试的练习 https://go.dev/tour/moretypes/26。
Can someone explain why the output starts from 0, 1, 1, 2, 3, 5 ....
instead of 1, 1, 2, 3, 5, .....?
如果周围的函数return通过显式return语句执行,延迟函数在该return语句设置任何结果参数之后但在函数[=17之前执行=]s 给它的调用者
Defer_statements
因为 defer 函数执行并将 a 的值从 0 更改为 1 但 a 的值已经是 return 明确的。
func fibonacci() func() int {
a, b := 0, 1
return func() int {
defer func() {a, b = b, a + b}()
return a
}
}
defer
在 return a
之后执行,此时更改局部变量 a
的值为时已晚。
您可能将它与 defer
更改命名的 return 值混淆了。这是不同的情况,因为即使在 return
之后更改它,函数实际上也会 return 它。
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
a, b := 0, 1
return func() int {
defer func() {a, b = b, a + b}()
return a
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
谁能解释为什么输出从 0, 1, 1, 2, 3, 5 .... 而不是 1, 1, 2, 3, 5, ..... 开始?
据我了解,defer 会在 return 语句之前执行,这意味着 a、b 已更新为 1、1 并且 1 应该被 returned?也许它与表达式被评估或绑定的时间有关,也许 return 已经将 a 绑定为 0,然后在 returning 之前检查是否存在 defer 语句?
go 中的任何内部代码参考都会非常有帮助。
编辑 1:这是我在了解 defer 后尝试的练习 https://go.dev/tour/moretypes/26。
Can someone explain why the output starts from 0, 1, 1, 2, 3, 5 .... instead of 1, 1, 2, 3, 5, .....?
如果周围的函数return通过显式return语句执行,延迟函数在该return语句设置任何结果参数之后但在函数[=17之前执行=]s 给它的调用者 Defer_statements
因为 defer 函数执行并将 a 的值从 0 更改为 1 但 a 的值已经是 return 明确的。
func fibonacci() func() int {
a, b := 0, 1
return func() int {
defer func() {a, b = b, a + b}()
return a
}
}
defer
在 return a
之后执行,此时更改局部变量 a
的值为时已晚。
您可能将它与 defer
更改命名的 return 值混淆了。这是不同的情况,因为即使在 return
之后更改它,函数实际上也会 return 它。