有效的Go 表示以下有关延期:
延迟函数的参数(如果函数是方法,包括接收器)在延迟执行时计算,而不是在调用执行时计算.除了避免担心变量在函数执行时更改值,这意味着单个延迟调用站点可以推迟多个函数执行.这是一个愚蠢的例子.
Run Code Online (Sandbox Code Playgroud)for i := 0; i < 5; i++ { defer fmt.Printf("%d ", i) }延迟函数以LIFO顺序执行,因此该
4 3 2 1 0函数返回时将打印此代码.
这个例子让我很困惑.如果在执行延迟调用时评估参数,那么for循环中5 5 5 5 5的延迟应该打印,因为当for循环结束时将调用defer ,并且此时i将为5. 在for循环结束时评估延迟将因此导致所有呼叫都为5.
我在这里错过了什么吗?
Von*_*onC 45
这似乎是连贯的(另见" 延迟,恐慌和恢复 ")
在周围函数返回后,延迟函数调用以Last In First Out顺序执行.
此功能打印"3210":
func b() {
for i := 0; i < 4; i++ {
defer fmt.Print(i)
}
}
Run Code Online (Sandbox Code Playgroud)
defer评估时的最后一次调用意味着i=3,前一个到最后一个意味着i=2等等.
每次
defer执行" "语句时,将像往常一样评估调用的函数值和参数,并重新保存,但不执行实际的函数体.
在
defers将被调用时,FUNC结束
是的,但是他们的参数在循环运行之前进行了评估.
当你使用闭包(函数文字)时,你在" 如何golang"推迟"捕获闭包的参数? "中有一个更棘手的延迟案例,详见" Golang中封闭体后的 " 为什么添加" ? ".()
我认为您对“延迟执行”和“执行呼叫”这两个短语的含义感到困惑。我相信,“延迟执行”是指控制流到达以开头的行defer,即在循环内发生了五次。相反,“调用执行” fmt.Printf("%d ", i)是执行时,即周围的函数返回时。
如果此解释正确,则您的语句“因为将在for循环结束时调用defers”是错误的(printf将在循环之后调用,但defer在内部调用),并且所有内容均与其他答案中解释的行为一致。
| 归档时间: |
|
| 查看次数: |
24028 次 |
| 最近记录: |