猿问

if 语句中已分配但未使用的值

我写了一个我在去操场上看到的问题的例子: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)

}


白衣染霜花
浏览 214回答 2
2回答

萧十郎

您正在块中创建foo一个if 新 变量:=foo, found := os.LookupEnv("GOPATH")检查块和范围规则。正确的代码:package mainimport (    "fmt"    "os")func main() {    var foo string    var found bool    if true {        foo = "foo"    } else {        foo, found = os.LookupEnv("GOPATH")        if !found {            fmt.Printf("who cares.\n")        }    }    println(foo)}

长风秋雁

来自 Go 文档:在块中声明的标识符可以在内部块中重新声明。虽然内部声明的标识符在范围内,但它表示由内部声明声明的实体。:= 在 else 块中重新声明了 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 中还有另一种不同类型的合法重新声明:与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初是在同一块(或参数列表,如果该块是函数体)中以相同类型声明的,并且至少有一个非空白变量是新的。因此,重新声明只能出现在多变量短声明中。重新声明不引入新变量;它只是为原始值分配一个新值。所以在另一种类型的重新声明中,实际上并没有创建新的 foo 变量,它的工作方式就像对 foo 的赋值。
随时随地看视频慕课网APP

相关分类

Go
我要回答