分配的值,不在if语句中使用

时间:2016-06-07 20:41:29

标签: go

我写了一个我在游乐场看到的问题的例子: https://play.golang.org/p/rPCqAC56Ff

这很明显,但是我在if语句之外声明一个变量,在if中设置变量然后在if之外使用。

问题很简单,为什么这不起作用?

package main

import (
    "fmt"
    "os"
)

func main() {
    var foo string
    if true {
        foo = "foo"
    } else {
        foo, found := os.LookupEnv("GOPATH")
        if !found {
            fmt.Printf("who cares.\n")
        }
    }
    println(foo)
}

2 个答案:

答案 0 :(得分:5)

您使用:=

def make_combinations(x): for a,b in itertools.combinations(x[1], 2): yield ','.join(map(str, [a,b,1])) if a < b else ','.join(map(str, [b,a,1])) 中创建新变量foo
if

检查blocks和范围rules

正确的code

foo, found := os.LookupEnv("GOPATH")

答案 1 :(得分:2)

来自Go文档:

  

块中声明的标识符可以在内部块中重新声明。   虽然内部声明的标识符在范围内,但它表示   内部声明声明的实体。

:=在else block redeclares foo中,所以foo现在引用一个具有相同名称的全新变量,一个从未使用过的变量。即使我们以某种方式到达了else块,最后一行的println(foo)也不会打印我们的$ GOPATH,因为它存储在另一个foo变量中(或直到整个变量超出范围)

正确的代码是:

func main() {
    var foo string
    if true {
        foo = "foo"
    } else {
        var found bool
        foo, found = os.LookupEnv("GOPATH")
        if !found {
            fmt.Printf("who cares.\n")
        }
    }
    println(foo)
}

很容易混淆,因为这个代码工作正常,即使foo在使用之前重新声明:

func main() {
    var foo string
    foo = "foo"
    foo, found := os.LookupEnv("GOPATH")
    if !found {
        fmt.Printf("who cares.\n")
    }
    println(foo)
}

这里发生的事情是,Go中还有另一种不同的法律重新声明:

  

与常规变量声明不同,是一个简短的变量声明   可以重新声明变量,只要它们最初是在之前声明的   在同一个块中(如果块是函数,则参数列出)   body)具有相同的类型,以及至少一个非空白变量   是新的。因此,重新声明只能出现在   多变量简短声明。 重新声明不会引入   新变量;它只是为原始版本赋予了一个新值。

所以在其他类型的重新声明中,实际上没有创建新的foo变量,它就像赋予foo一样。