2016-03-09 128 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

A嵌段是聲明和內匹配的括號括號語句 的可能是空的序列。

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

除了在源代碼中明確的塊,有隱含 塊:

  • 宇宙塊包括所有轉到源文本。

  • 每個軟件包都有一個軟件包塊,其中包含該軟件包的所有Go源文本。

  • 每個文件都有一個文件塊,其中包含該文件中的所有Go源文本。

  • 每個「if」,「for」和「switch」語句都被認爲是在它自己的隱式塊中。

  • 「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」,「for」或「switch」語句的初始值設定項的某些上下文中,短變量聲明可用於聲明本地臨時變量。

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

vpcGrp是設置但未讀取的局部變量;它沒有被使用。 err是一個局部變量,它既被設置又被讀取;它被使用了。

由於vpcGrperr已經在外部範圍被宣佈,嘗試

vpcGrp, err = createDbSecurityGrp(grpName, vpcId, region) 
相關問題