将变量传递给回调函数

时间:2019-10-17 07:47:46

标签: go

是将selector变量传递给回调函数的方法吗?

for _, selector := range listSelector {
    c.OnHTML(selector, func(e *colly.HTMLElement) {
        fmt.Println(selector) // Similar outputs
    })
}

预期结果是输出的不同选择器。 谢谢。

1 个答案:

答案 0 :(得分:1)

取决于何时执行回调,您可能需要在块内创建迭代变量的副本,并在闭包中使用它。

for _, selector := range listSelector {
    sel := selector // create a copy
    c.OnHTML(sel, func(e *colly.HTMLElement) {
        fmt.Println(sel) // Similar outputs
    })
}

如果执行了回调并且在循环中的下一次迭代之前退出,则无需执行此操作,但是,如果在某个时间之后执行回调,则需要将迭代变量的副本传递给闭包。这是因为重用迭代变量来保存迭代值,这意味着当前迭代中的变量值将被下一次迭代中的值覆盖。

来自spec

  

可以通过“ range”子句使用   短变量声明(:=)的形式。在这种情况下,它们的类型是   设置为各个迭代值的类型,其范围为   “ for”语句的框; 它们在每次迭代中都会重复使用。   如果迭代变量在“ for”语句之外声明,   执行后,它们的值将是最后一次迭代的值。


如果您有兴趣,可以在Effective Go关于渠道的文档中对此进行更好的解释。