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

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

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

Go
白衣染霜花 2022-01-17 16:33:41
我写了一个我在去操场上看到的问题的例子:https: //play.golang.org/p/rPCqAC56Ff这是不言而喻的,但我在 if 语句之外声明一个变量,在 if 中设置变量,然后在 if 之外使用。问题很简单,为什么这不起作用?package mainimport (    "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 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

您正在块中创建foo一个if 新 变量:=


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

检查块和范围规则。


正确的代码:


package main


import (

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

}


查看完整回答
反对 回复 2022-01-17
?
长风秋雁

TA贡献1757条经验 获得超7个赞

来自 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 的赋值。


查看完整回答
反对 回复 2022-01-17
  • 2 回答
  • 0 关注
  • 178 浏览
慕课专栏
更多

添加回答

举报

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