【问题标题】:Redeclare a variable for convenience in golang?为了方便在golang中重新声明一个变量?
【发布时间】:2017-12-11 17:25:48
【问题描述】:

这段代码:

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, playground")

    var a bool
    var b interface{}
    b = true
    if a, ok := b.(bool); !ok {
        fmt.Println("Problem!")
    }
}

在 golang 操场上产生这个错误:

tmp/sandbox791966413/main.go:11:10: a declared and not used
tmp/sandbox791966413/main.go:14:21: a declared and not used

这很令人困惑,因为我们在简短的变量声明 golang docs 中读到:

与常规变量声明不同,短变量声明可以 重新声明变量,前提是它们最初是在 相同的块(如果块是函数,则为参数列表 body) 具有相同的类型,并且至少有一个非空白变量 是新的。因此,重新声明只能出现在 多变量短声明。重新声明并未引入 新变量;它只是为原始值分配一个新值。

所以,我的问题:

  1. 为什么我不能在上面的代码 sn-p 中重新声明变量?
  2. 假设我真的做不到,我真的喜欢做的是找到 一种用函数的输出填充变量的方法,同时 以更简洁的方式检查错误。那么有什么办法吗 改进以下形式以从 可出错的功能?

    var A RealType
    if newA, err := SomeFunc(); err != nil {
        return err
    } else {
        A = newA
    }   
    

【问题讨论】:

    标签: go


    【解决方案1】:

    发生这种情况是因为您在 if 初始化语句中使用了短变量声明,它引入了一个新范围。

    而不是这样,a 是一个新变量,它会影响现有变量:

    if a, ok := b.(bool); !ok {
        fmt.Println("Problem!")
    }
    

    你可以这样做,a 被重新声明:

    a, ok := b.(bool)
    if !ok {
        fmt.Println("Problem!")
    }
    

    这是因为ok 是一个新变量,所以你可以重新声明a 并且你引用的段落是有效的。

    同样,你的第二个代码 sn-p 可以写成:

    A, err := SomeFunc()
    if err != nil {
        return err
    }
    

    【讨论】:

    • 我想这有点短,在 if 之外使用短 decls。
    【解决方案2】:

    您确实重新声明了变量,这就是问题所在。当您重新声明一个变量时,它是一个不同的变量。这被称为“阴影”。

    主包

    import (
        "fmt"
    )
    
    func main() {
        fmt.Println("Hello, playground")
    
        // original a.
        var a bool
        var b interface{}
        b = true
        // redeclared a here. This is a a'
        if a, ok := b.(bool); !ok {
            // a' will last until the end of this block
            fmt.Println("Problem!")
        }
        // a' is gone. So using a here would get the original a.
    }
    

    关于你的第二个问题。该代码看起来很棒。我可能会将其切换为 if err == nil (并交换 if 和 else 块)。但这是一种风格。

    【讨论】:

    • “当你重新声明一个变量时,它是一个不同的变量。”只有当作用域不同时才成立。当我们在同一个作用域内重新声明一个变量时,它只是给原来的变量赋了一个新值。
    • 根据规范:“没有标识符可以在同一个块中声明两次。”所以你是对的,它是同一个变量,但那是因为它不能被重新声明。当一个变量被重新声明时,它总是在一个内部块(新范围)内完成。在这种情况下,新的作用域是 if 语句。
    【解决方案3】:

    编译器引发的错误是变量a 的两个声明都没有被使用。 你实际上是在声明 a 两次,当在 if 条件中使用短声明时,你正在创建一个新的范围,它会隐藏变量的先前声明。

    您面临的实际问题是您从未使用变量值,在 Go 中,这被视为编译时错误。


    关于你的第二个问题,我认为获取值和检查错误的最短方法是执行类似的操作:

    func main() {
        a, ok := someFunction()
        if !ok {
            fmt.Println("Problem!")
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      相关资源
      最近更新 更多