2016-08-04 7 views
2

В documenation состояния:Go: многократная перекраска, когда внутри цикла for создается новая переменная?

Как следствие, переопределение может появиться только в нескольких переменных короткой декларации. Redeclaration не вводит новую переменную; он просто присваивает новое значение оригиналу.

Но как это работает для циклов? See this example. Кажется, что переменная «nextPos», которая имеет область вне цикла, фактически получает переопределенную внутри цикла для внутренней области и, следовательно, теряет свое значение для каждой итерации. This версия работает.

+0

Go имеет блочно-объем (в отличие, скажем, Javascript). Когда вы объявляете переменную, она объявляется внутри своего «окружающего блока». Поскольку вы можете иметь вложенные блоки, вы можете объявить переменную с тем же именем во внутреннем блоке, что и внешняя. Это называется затенением. – thwd

ответ

2

Давайте покажем, как это работает, с этими образцами кода:

Давайте упрощать свой первый образец, увидеть этот рабочий пример кода (1):

package main 

import "fmt" 

func main() { 
    a := 100 
    { 
     fmt.Println(a) // 100 
     a, b := 0, 0 
     fmt.Println(a, b) // 0 0 
    } 
    fmt.Println(a) // 100 
} 

выход:

100 
0 0 
100 

так a в a, b := 0, 0 is затененный, этот a является новой переменной,
это называется областью видимости и затенения переменной,
и вы можете назвать ее, например.c как этот код на данный момент, чтобы показать, как это работает (2):

package main 

import "fmt" 

func main() { 
    a := 100 
    { 
     fmt.Println(a) // 100 
     c, b := 0, 0 
     fmt.Println(c, b) // 0 0 
    } 
    fmt.Println(a) // 100 
} 

вывод, что так же, как (1):

100 
0 0 
100 

и позволяет упростить следующий пример кода (3):

package main 

import "fmt" 

func main() { 
    a := 0 
    b := byte(0) 
    { 
     fmt.Println(a, b) // 0 0 
     a, b = 1, byte(1) 
     fmt.Println(a, b) // 1 1 
    } 
    fmt.Println(a, b) // 1 1 
} 

выход:

0 0 
1 1 
1 1 

, поэтому здесь a и b - это тот же внутренний и внешний контур.

также смотрите: Where can we use Variable Scoping and Shadowing in Go?
и посмотреть: What is the difference between := and = in Go?

+1

Спасибо. Это не было ясно из документации – sebdehne

1

Вот как работает короткое заявление о назначении :=. Из спецификации:

В отличие от обычных объявлений переменных, короткое объявление переменной может переобъявить переменных при условии, что они первоначально были объявлены ранее в тот же блок (или список параметров, если блок является телом функции ) с такого же типа, и по крайней мере одна из незапущенных переменных является новой. Как следствие, повторная декларация может появляться только в короткой декларации с несколькими переменными . В Redeclaration не вводится новая переменная ; он просто назначает новое значение оригиналу.

Таким образом, в первом примере, вы можете увидеть, что есть одна новая переменная, а именно nextB, и это вновь заявляет nextPos, а также для каждой итерации цикла.

Во втором случае как nextB, так и nextPos уже объявлены и, следовательно, не происходит повторного объявления. Также обратите внимание, что вы используете =, поскольку компилятор не разрешил := по той же причине, то есть не объявляли новые переменные.

Смежные вопросы