15

根据我对规范的阅读:

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

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()
}

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

4

2 回答 2

14

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

于 2012-07-08T12:16:48.193 回答
0

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

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

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

x := x + 1

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

于 2016-09-21T15:17:20.797 回答