为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕哥6287543 2023-04-04 14:26:34
我偶然发现了一个奇怪的问题,下面的代码无法编译: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 推荐的代码):$ go run main.go# command-line-arguments./main.go:13:5: tm declared and not used注意tm变量确实被使用了。但是,如果我添加一个 else 块 - 一切都按预期编译: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)编辑:到目前为止所有的回应者。根据:https: //golang.org/ref/spec#Short_variable_declarations与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初是在同一块(如果块是函数体,则为参数列表)中较早声明的,具有相同的类型,并且至少有一个非空变量是新的。因此,重新声明只能出现在多变量简短声明中。重新声明不会引入新变量;它只是为原始值分配了一个新值。
查看完整描述

2 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

这部分:

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

创建一个仅在语句内具有范围的变量- 它不是您声明为的变量。tmifvar tm time.Time

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

要解决此问题:声明err并更改if为:

var err errorif tm, err = time.Parse(...)

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


查看完整回答
反对 回复 2023-04-04
?
温温酱

TA贡献1752条经验 获得超4个赞

您的if语句声明了一个新变量tm,该变量仅存在于if块的范围内并且确实从未使用过:

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

在 Go 中,:=声明一个变量并对其进行初始化。你的意思可能是:

func main() {

    var val reflect.Value

    var tm time.Time

    var err error


    // Note the change to normal assignment here instead of :=

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

}

shortcut运算符在Go Tour of Go:=中进行了演示,并在Go spec中进行了解释,后者包括:

它是带有初始化表达式但没有类型的常规变量声明的简写:

"var" IdentifierList = ExpressionList .

Go 规范中也解释了作用域。


查看完整回答
反对 回复 2023-04-04
  • 2 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信