2016-03-09 3 views
2

Я новичок в Go и задаюсь вопросом, почему Go думаю, что я не использую vpcGrp? Как бы вы это кодировали?Почему Go думает, что я не использую объявленную переменную?

Вот мой код:

var vpcGrp *ec2.SecurityGroup 
grpExists := false 
resp, err := svc.DescribeSecurityGroups(params) 
if err != nil { 
    log.Error(err) 
} else { 
    for _, v := range resp.SecurityGroups { 
     if *v.GroupName == grpName { 
      log.Debug("VPC Security Group Found [", grpName, "]") 
      vpcGrp = v 
      grpExists = true 
     } 
    } 
} 

if !grpExists { 
    vpcGrp, err := createDbSecurityGrp(grpName, vpcId, region) 
    if err != nil { 
     log.Error(err) 
     return nil, err 
    } 
} 

return vpcGrp, nil 

ответ

7

The Go Programming Language Specification

Blocks

Блок представляет собой, возможно, пустая последовательность деклараций и заявлений в пределах соответствия фигурных скобок скобки.

Block = "{" StatementList "}" . 
StatementList = { Statement ";" } . 

В дополнение к явным блокам в исходном коде, есть неявное блоки:

  • Блок Вселенная охватывает все Перейти исходный текст.

  • В каждом пакете есть пакетный блок, содержащий весь исходный текст Go для этого пакета.

  • Каждый файл имеет файловый блок, содержащий весь исходный текст Go в этом файле.

  • Каждый оператор «если», «для» и «переключатель» считается в своем неявном блоке.

  • Каждое предложение в выражении «switch» или «select» действует как неявный блок.

Блокировка гнезда и влияние области.

Declarations and scope

декларация связывает непустой идентификатор постоянная, типа, переменных, функция, этикетку или упаковку. Каждый идентификатор в программе должен быть объявлен. Идентификатор не может быть объявлен дважды в том же блоке , и ни один идентификатор не может быть объявлен как в файле, так и в пакете .

Пустой идентификатор может использоваться как любой другой идентификатор в объявлении , но он не вводит привязку и, следовательно, не объявляется . В блоке пакета инициализатор идентификатора может использоваться только для для деклараций функции init, и, как и пустой идентификатор, он не вводит новую привязку.

Declaration = ConstDecl | TypeDecl | VarDecl . 
TopLevelDecl = Declaration | FunctionDecl | MethodDecl . 

Объем заявленного идентификатора является степень исходного текста в котором идентификатор обозначает заданную константу, тип, переменную, функцию , этикетку или упаковку.

Перейти в лексической области видимости с использованием блоков:

  • Объем стандартного идентификатором является вселенная блока.
  • Объем идентификатора, обозначающий константу, тип, переменную или функцию (но не метод), объявленную на верхнем уровне (вне любой функции) - это пакетный блок.
  • Объем имени пакета импортированного пакета является файловым блоком файла, содержащего декларацию импорта.
  • Объем идентификатора, обозначающего приемник метода, функциональный параметр или переменную результата, является телом функции.
  • Объем константного или переменного идентификатора, объявленного внутри функции, начинается в конце ConstSpec или VarSpec (ShortVarDecl для коротких объявлений переменных) и заканчивается в конце самого внутреннего , содержащего блок.
  • Объем идентификатора типа, объявленного внутри функции, начинается с идентификатора в TypeSpec и заканчивается в конце самого внутреннего , содержащего блок.

Идентификатор, объявленный в блоке, может быть переоформлен во внутреннем блоке. Хотя идентификатор внутреннего объявления относится к области видимости, он обозначает объект, объявленный внутренней декларацией.

Short variable declarations

Короткое описание переменный используется следующий синтаксис:

ShortVarDecl = IdentifierList ":=" ExpressionList . 

Это сокращенное для регулярной декларации переменной с инициализатором выражениями, но нет типов:

"var" IdentifierList = ExpressionList . 

Коротких объявления переменных могут отображаться только внутри функций. В некоторых контекстах , таких как инициализаторы для операторов «if», «for» или «switch» , они могут использоваться для объявления локальных временных переменных.

Каждый оператор «если», «для» и «переключатель» считается в своем неявном блоке.

Идентификатор, объявленный в блоке, может быть переоформлен во внутреннем блоке. Хотя идентификатор внутреннего объявления находится в области видимости, он обозначает объект, объявленный внутренней декларацией.

В некоторых контекстах, таких как инициализаторы для операторов «if», «for» или «switch», короткие объявления переменных могут использоваться для объявления локальных временных переменных.

if !grpExists { 
    vpcGrp, err := createDbSecurityGrp(grpName, vpcId, region) 
    if err != nil { 
     log.Error(err) 
     return nil, err 
    } 
} 

vpcGrp локальная переменная, которая устанавливается, но не читал; он не используется. err - это локальная переменная, которая устанавливается и считывается; он используется.

С vpcGrp и err уже объявлена ​​во внешней области видимости, попытайтесь

vpcGrp, err = createDbSecurityGrp(grpName, vpcId, region) 
Смежные вопросы