35

In the Go web server example here: http://golang.org/doc/effective_go.html#web_server

The following line of code works

var addr = flag.String("addr", ":1718", "http service address")

but changing it to

addr := flag.String("addr", ":1718", "http service address")

is a compilation error. Why? Does it have anything to do with the face that the return type of the function is *string instead of string? What difference does that make?

UPDATE: Thanks for pointing out that := is not allowed at the top level. Any idea why this inconsistency is in the spec? I don't see any reason for the behaviour to be different inside a block.

4

3 回答 3

32

在 Go 中,顶级变量赋值必须var关键字为前缀。var仅允许在块内省略关键字。

package main

var toplevel = "Hello world"         // var keyword is required

func F() {
        withinBlock := "Hello world" // var keyword is not required
}
于 2014-02-09T09:49:04.167 回答
21

关于更新的问题:长声明和短声明之间实际上存在差异,采用这种短形式允许重新声明变量。

规格

与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初是在同一块中以相同类型声明的,并且至少有一个非空白变量是新的。因此,重新声明只能出现在多变量短声明中。重新声明不引入新变量;它只是为原始值分配一个新值。

field1, offset := nextField(str, 0)
field2, offset := nextField(str, offset)  // redeclares offset
a, a := 1, 2                              // illegal: double declaration of a or no new variable if a was declared elsewhere

所以我会说:=运算符不是纯粹的declare,而是更像declare 和 assign。不允许在顶层重新声明,因此也不允许短声明。

另一个原因可能是语法简单。type在 Go 中,所有顶级表单都以、var或开头func。简短的声明会毁掉所有的可爱。

于 2014-02-09T13:28:06.727 回答
10

Go 编程语言规范

简短的变量声明

简短的变量声明使用以下语法:

ShortVarDecl = IdentifierList ":=" ExpressionList .

短变量声明可能只出现在函数内部。

在您的示例中,更改函数体外部的变量声明语句

var addr = flag.String("addr", ":1718", "http service address")

到函数体外部的简短变量声明语句

addr := flag.String("addr", ":1718", "http service address")

编译器错误“函数体外部的非声明语句”失败。

于 2014-02-09T10:22:39.727 回答