从我阅读规范:
短变量声明...是常规变量的简写 声明与初始化表达式但没有类型......
我原以为这两者是相同的:
var f func()
f = func() {
...
}
和
f := func() {
...
}
但似乎他们不是。我试图在外部函数中包含一个自递归函数,但这有效:
func myOuter() {
var f func()
f = func() {
f()
}
f()
}
但这不是,在内部函数中说undefined: f
。
func myOuter() {
f := func() {
f()
}
f()
}
那有什么区别? 有没有办法用简短的声明来写这个,或者我必须用长手写出来吗?
答案 0 :(得分:14)
f := func() { /* ... */ }
与var f func() = func() { /* ... */ }
相同(但在包级别只允许后一个)。在您的特定情况下,这两个变体都不起作用,因为语句将从右到左进行评估。正如您已经建议的那样,解决方案是将语句拆分为两个。一个用于声明变量,另一个用于为其分配递归函数。
答案 1 :(得分:0)
前两个代码示例在一个条件下语义相同:分配给变量的表达式需要在编译时解析。
除非您尝试分配引用刚刚声明的变量(或函数)的表达式,否则在每种情况下都是相同的。这里的问题是因为golang是以右关联方式解析的,所以在将其分配给左边之前,它会尝试键入解析右边的表达式。如果引用declare-assign运算符左侧的变量,则引用编译器尚不知道的变量,因此undefined: f
。
另一个产生类似结果的例子:
x := x + 1
虽然人们尝试这种情况的情况要少得多,因为更明显的是x还没有被分配。