donglusou3335 2018-09-11 18:04
浏览 69
已采纳

短变量声明和“变量已声明且未使用”错误

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))
}

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

Note the tm variable is indeed used.

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))
}

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

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.

  • 写回答

2条回答 默认 最新

  • duanhongxian6982 2018-09-11 18:11
    关注

    This part:

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

    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.

    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.

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

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

    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).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗
  • ¥15 钢筋实图交点识别,机器视觉代码
  • ¥15 如何在Linux系统中,但是在window系统上idea里面可以正常运行?(相关搜索:jar包)
  • ¥50 400g qsfp 光模块iphy方案
  • ¥15 两块ADC0804用proteus仿真时,出现异常
  • ¥15 关于风控系统,如何去选择
  • ¥15 这款软件是什么?需要能满足我的需求
  • ¥15 SpringSecurityOauth2登陆前后request不一致