Var vs: = in Go
В примере веб-сервера Go: http://golang.org/doc/effective_go.html#web_server
Следующая строка кода работает
var addr = flag.String("addr", ":1718", "http service address")
но изменив его на
addr := flag.String("addr", ":1718", "http service address")
- ошибка компиляции. Зачем? Имеет ли это какое-либо отношение к лицу, что тип возврата функции *string
вместо string
? Какая разница?
UPDATE: Спасибо, что указали, что :=
не разрешено на верхнем уровне. Любая идея, почему эта несогласованность находится в спецификации? Я не вижу причин, чтобы поведение отличалось внутри блока.
Ответы
Ответ 1
В обновленном вопросе: на самом деле существует разница между длинными и короткими объявлениями, находящимися в той короткой форме, позволяющей переопределять переменные.
От spec:
В отличие от обычных объявлений переменных краткое объявление переменной может обновлять переменные, если они были изначально объявлены ранее в том же блоке с одним и тем же типом, и по крайней мере одна из непустых переменных является новой. Как следствие, переопределение может появляться только в короткой декларации с несколькими переменными. В Redeclaration не вводится новая переменная; он просто назначает новое значение оригиналу.
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
Итак, я бы сказал, что оператор :=
не является чистым объявлением, но более похож на объявление и назначение.
Не допускается повторная декларация в верхнем слое, поэтому ни краткие декларации.
Другой причиной этого может быть простота синтаксиса. В Go все формы верхнего уровня начинаются с type
, var
или func
. Короткие объявления там разрушат всю симпатичность.
Ответ 2
В Go, назначения переменных верхнего уровня должны иметь префикс с ключевым словом var
. Опускание ключевого слова var
разрешено только внутри блоков.
package main
var toplevel = "Hello world" // var keyword is required
func F() {
withinBlock := "Hello world" // var keyword is not required
}
Ответ 3
Спецификация языка программирования Go
Объявления коротких переменных
Объявление короткой переменной использует синтаксис:
ShortVarDecl = IdentifierList ":=" ExpressionList .
Короткие объявления переменных могут отображаться только внутри функций.
В вашем примере изменение оператора объявления переменной вне тела функции
var addr = flag.String("addr", ":1718", "http service address")
в короткий оператор объявления переменной за пределами тела функции
addr := flag.String("addr", ":1718", "http service address")
не удается с ошибкой компилятора "выражение без декларации вне тела функции".