【问题标题】:What's the closure scoping difference between short variable declarations and long ones in Go?Go 中的短变量声明和长变量声明之间的闭包范围区别是什么?
【发布时间】:2012-07-08 03:08:42
【问题描述】:

根据我对规范的阅读:

简短的变量声明...是常规变量的简写 带有初始化表达式但没有类型的声明...

http://golang.org/ref/spec

我还以为两者是一样的:

var f func()
f = func() {
    ...
}

f := func() {
    ...
}

但似乎他们不是。我试图在外部函数中包装一个自递归函数,但这有效:

func myOuter() {
    var f func()

    f = func() {
        f()
    }

    f()
}

但这不是,在内部函数中说undefined: f

func myOuter() {
    f := func() {
        f()
    }

    f()
}

那么有什么区别呢? 有没有办法用简短的声明来写这个,或者我必须把它写出来?

【问题讨论】:

  • 谢谢Kissaki,我显然错误地粘贴了两次。

标签: recursion closures go


【解决方案1】:

在一个条件下,您的前两个代码示例在语义上是相同的:分配给变量的表达式需要在编译时解析。

这在任何情况下都是相同的,除非您尝试分配引用刚刚声明的变量(或函数)的表达式。这里的问题是,因为 golang 是右关联解析的,它会在将其分配给左侧之前尝试在右侧键入 resolve 表达式。如果您引用声明分配运算符左侧的变量,则您引用的是编译器尚不知道的变量,因此undefined: f

另一个会产生类似结果的例子:

x := x + 1

虽然这对于人们来说不太常见,因为很明显 x 还没有被分配。

【讨论】:

    【解决方案2】:

    f := func() { /* ... */ }var f func() = func() { /* ... */ } 相同(但在包级别只允许使用后者)。在您的特定情况下,这两种变体都不起作用,因为该语句将从右到左进行评估。解决方案是 - 正如您已经建议的那样 - 将语句分成两部分。一个用于声明变量,另一个用于为其分配递归函数。

    【讨论】:

    • 谢谢!我没有想到命令或声明。
    • 啊!现在我必须再次修复我的代码,感谢您的洞察力!
    猜你喜欢
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 2015-07-29
    • 2013-11-19
    • 1970-01-01
    • 2020-03-18
    • 2014-09-20
    相关资源
    最近更新 更多