为了方便起见,在Golang中重新声明一个变量?

时间:2017-12-11 17:25:48

标签: go

此代码:

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. 为什么我不能在上面的代码段中重新声明变量?
  2. 假设我真的无法做到, 一种用函数输出填充变量的方法 以更简洁的方式检查错误。所以有什么办法 改进以下表格以获得价值 错误的功能?

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

3 个答案:

答案 0 :(得分:4)

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

而不是这个,a是一个隐藏现有变量的新变量:

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

你可以这样做,重新宣布a

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

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

同样,您的第二个代码段可以写成:

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

答案 1 :(得分:1)

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

package main

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

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

答案 2 :(得分:0)

编译器引发的错误是,未使用变量a的两个声明。 实际上,您在a中声明了两次,而在if条件中使用短声明时,您正在创建一个新的作用域,该作用域遮盖了变量的先前声明。

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


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

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