简短的变量声明和“已声明变量且未使用".错误 [英] Short variable declaration and "variable declared and not used" error

查看:97
本文介绍了简短的变量声明和“已声明变量且未使用".错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了以下代码无法编译的奇怪问题:

I've stumbled across a strange issue where the code below fails to compile:

func main() {
    var val reflect.Value
    var tm time.Time

    if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {
        panic(err)
    }
    val = reflect.ValueOf(tm)

    fmt.Println(val, tm, reflect.TypeOf(tm))
}

出现错误(代码是linter推荐的代码).

with the error (the code is what linter recommends).:

$ go run main.go
# command-line-arguments
./main.go:13:5: tm declared and not used

请注意,确实使用了tm变量.

Note the tm variable is indeed used.

但是,如果我添加了else块-一切都会按预期编译:

If however I add an else block - everything compiles as expected:

func main() {
    var val reflect.Value
    var tm time.Time

    if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {
        panic(err)
    } else {
        val = reflect.ValueOf(tm)
    }

    fmt.Println(val, tm, reflect.TypeOf(tm))
}

这看起来像是编译器中的错误,还是一个已知问题?任何的想法? (我正在使用go 1.11)

This looks like a bug in the compiler or perhaps a known issue? Any idea? (I'm using go 1.11)

edit:到目前为止的所有响应对象.按照: https://golang.org/ref/spec#Short_variable_declarations

edit: to all respondends so far. As per: https://golang.org/ref/spec#Short_variable_declarations

与常规变量声明不同,简短的变量声明可能 重新声明变量,前提是它们最初是在以下位置声明的 相同的块(如果该块是功能,则参数列出 正文),并且具有至少一个非空白变量 是新的.因此,重新声明只能出现在 多变量简短声明.重新声明不会引入 新变量;只是为原始值分配了一个新值.

Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.

推荐答案

此部分:

if tm, err := time.Parse(...)

创建一个 new 变量tm,该变量仅在if语句中具有作用域-而不是您声明为var tm time.Time的变量.

creates a new variable tm that has scope only within the if statement - it is NOT the one you declared as var tm time.Time.

if中未使用此新变量,因此会出现错误.请注意,您也没有分配外部级别tm,因此fmt.Println将打印零时间,而不是时间.Parse返回.

This new variable is not used within the if, therefore you get the error. Note you also don't get the outer-level tm assigned, so fmt.Println will print the zero time, not what time.Parse returned.

要解决此问题,请执行以下操作: 声明err并将您的if更改为:

To fix this: declare err and change your if to read:

var err error
if tm, err = time.Parse(...)

请注意,这在GO中是一个微妙的事情,并且是错误的相当普遍的来源.实际上,:=语句可以与已经声明的变量和一个或多个 new 变量混合使用-如果已经声明的变量在相同的词法范围内.然后,:=仅自动声明新的,其余的仅被分配(与=一样).但是,如果在新作用域中使用:=,则将在该作用域中声明ALL变量,并屏蔽具有相同名称的任何外部作用域变量(例如在if中;请注意,if条件不是在括号内,但仍被认为是在{code}块内; for和GO中的其他复合语句也会发生同样的情况.

NOTE this is a subtle thing in GO and a fairly common source of mistakes. The := statement can in fact be used with a mix of variables that are already declared and one or more new variables - if the already-declared ones are in the same lexical scope. Then, only the new ones are auto-declared by := and the rest are just assigned (as with =). However, if you use := in a new scope, then ALL variables are declared in that scope and mask any outer-scope variables with the same name (such as in an if; note that the if condition is not inside the braces, but is still considered as if it were within the {code} block; same happens with the for and other compound statements in GO).

这篇关于简短的变量声明和“已声明变量且未使用".错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆