dongying9756 2014-07-13 06:20
浏览 66
已采纳

Golang延迟行为

Effective Go states the following regarding defer:

The arguments to the deferred function (which include the receiver if the function is a method) are evaluated when the defer executes, not when the call executes. Besides avoiding worries about variables changing values as the function executes, this means that a single deferred call site can defer multiple function executions. Here's a silly example.

for i := 0; i < 5; i++ {
    defer fmt.Printf("%d ", i)
}

Deferred functions are executed in LIFO order, so this code will cause 4 3 2 1 0 to be printed when the function returns.

This example confuses me. If parameters are evaluated when the defer call is executed, then the defers in the for loop should print 5 5 5 5 5 since the defers will be called when the for loop ends, and at that time i would be 5. Evaluating defers at the end of the for loop will thus result in 5 for all calls.

Am I missing something here?

  • 写回答

3条回答 默认 最新

  • douke8473 2014-07-13 06:25
    关注

    That seems coherent (see also "Defer, Panic, and Recover")

    Deferred function calls are executed in Last In First Out order after the surrounding function returns.

    This function prints "3210":

    func b() {
        for i := 0; i < 4; i++ {
            defer fmt.Print(i)
        }
    }
    

    The last call when the defer is evaluated means i=3, the previous to last means i=2 and so on.

    Golang spec:

    Each time the "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function body is not executed.


    the defers will be called when func ends

    yes, but their arguments are evaluated before, while the loop is running.

    You have a trickier defer case in "How golang's “defer” capture closure's parameter?" when used with closure (function literal), as detailed in "Why add “()” after closure body in Golang?".

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?