doufu9836 2013-04-15 08:24
浏览 59
已采纳

golang的“延迟”如何捕获闭包的参数?

Here is my code (run):

package main

import "fmt"

func main() {
    var whatever [5]struct{}

    for i := range whatever {
        fmt.Println(i)
    } // part 1

    for i := range whatever {
        defer func() { fmt.Println(i) }()
    } // part 2

    for i := range whatever {
        defer func(n int) { fmt.Println(n) }(i)
    } // part 3
}

Output:

0 1 2 3 4 4 3 2 1 0 4 4 4 4 4

Question: What's the difference between part 2 & part 3? Why part 2 output "44444" instead of "43210"?

  • 写回答

2条回答 默认 最新

  • dtwr2012 2013-04-15 08:32
    关注

    The 'part 2' closure captures the variable 'i'. When the code in the closure (later) executes, the variable 'i' has the value which it had in the last iteration of the range statement, ie. '4'. Hence the

    4 4 4 4 4
    

    part of the output.

    The 'part 3' doesn't capture any outer variables in its closure. As the specs say:

    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 is not invoked.

    So each of the defered function calls has a different value of the 'n' parameter. It is the value of the 'i' variable in the moment the defer statement was executed. Hence the

    4 3 2 1 0
    

    part of the output because:

    ... deferred calls are executed in LIFO order immediately before the surrounding function returns ...


    The key point to note is that the 'f()' in 'defer f()' is not executed when the defer statement executes

    but

    the expression 'e' in 'defer f(e)' is evaluated when the defer statement executes.

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

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题