go - 为什么 Go 认为我没有使用声明的变量?

标签 go

我是 Go 的新手,想知道为什么 Go 认为我没有使用 vpcGrp?你会如何编码?

这是我的代码:

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

最佳答案

The Go Programming Language Specification

Blocks

A block is a possibly empty sequence of declarations and statements within matching brace brackets.

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

In addition to explicit blocks in the source code, there are implicit blocks:

  • The universe block encompasses all Go source text.

  • Each package has a package block containing all Go source text for that package.

  • Each file has a file block containing all Go source text in that file.

  • Each "if", "for", and "switch" statement is considered to be in its own implicit block.

  • Each clause in a "switch" or "select" statement acts as an implicit block.

Blocks nest and influence scoping.

Declarations and scope

A declaration binds a non-blank identifier to a constant, type, variable, function, label, or package. Every identifier in a program must be declared. No identifier may be declared twice in the same block, and no identifier may be declared in both the file and package block.

The blank identifier may be used like any other identifier in a declaration, but it does not introduce a binding and thus is not declared. In the package block, the identifier init may only be used for init function declarations, and like the blank identifier it does not introduce a new binding.

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

The scope of a declared identifier is the extent of source text in which the identifier denotes the specified constant, type, variable, function, label, or package.

Go is lexically scoped using blocks:

  • The scope of a predeclared identifier is the universe block.
  • The scope of an identifier denoting a constant, type, variable, or function (but not method) declared at top level (outside any function) is the package block.
  • The scope of the package name of an imported package is the file block of the file containing the import declaration.
  • The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body.
  • The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.
  • The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block.

An identifier declared in a block may be redeclared in an inner block. While the identifier of the inner declaration is in scope, it denotes the entity declared by the inner declaration.

Short variable declarations

A short variable declaration uses the syntax:

ShortVarDecl = IdentifierList ":=" ExpressionList .

It is shorthand for a regular variable declaration with initializer expressions but no types:

"var" IdentifierList = ExpressionList .

Short variable declarations may appear only inside functions. In some contexts such as the initializers for "if", "for", or "switch" statements, they can be used to declare local temporary variables.

每个“if”、“for”和“switch”语句都被视为在其自己的隐式 block 中。

block 中声明的标识符可以在内部 block 中重新声明。虽然内部声明的标识符在范围内,但它表示内部声明声明的实体。

在某些上下文中,例如“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)

关于go - 为什么 Go 认为我没有使用声明的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35903780/

相关文章:

json - 如何利用encoding/json UnmarshalTypeError 中的偏移值来更好地处理错误?

go - 结构中 slice 的初始化

dictionary - 解码到 map 中

postgresql - 无法从 db.QueryRow() 推断出错误

Go lang Redis PubSub 在不同的 go 路由中用于发布和订阅

postgresql - 临时 Postgres 表过早丢失

go - Golang应用的部署策略,如何在生产环境中运行Golang应用

go - 如何重构语义重复

mysql - Go-MySQL-驱动程序 : Prepared Statements with Variable Query Parameters

date - 在 Go 中解析时间字符串