【问题标题】:Declared and not used - How to update a variable in IF Statement已声明且未使用 - 如何更新 IF 语句中的变量
【发布时间】:2019-03-28 10:03:20
【问题描述】:

我正在尝试在 Go Lang 中设置一个具有默认值的 bool 变量并根据条件更新它。 func foo 编译,但函数 bar 没有编译并给出错误“f 已声明且未使用”

有一个related answer - 没有解释下一个问题

Go 中 this(bar 函数)的正确模式是什么?

代码如下:

package main

import (
"fmt"
"strconv"
)

func foo(m map[string]string) bool {
    f := false

if _, exists := m["READWRITE"]; exists {
    fmt.Println("Before Updating f : ", f)
    f, _ = strconv.ParseBool(m["READWRITE"])
    //if err != nil {
    //  panic(err)
    //}
}

fmt.Println("After Updating f : ", f)

return f
}

func bar(m map[string]string) bool {
    f := false

    if _, exists := m["READWRITE"]; exists {
         fmt.Println("Before Updating f : ", f)
         f, err := strconv.ParseBool(m["READWRITE"]) // error on this line "f declared and not used"
        if err != nil {
            panic(err)
        }
    }

    fmt.Println("After Updating f : ", f)

    return f
}

func main() {
    m := map[string]string{"READWRITE": "true"}

    fmt.Println(foo(m))
    fmt.Println(bar(m))
}

【问题讨论】:

标签: if-statement go variable-assignment


【解决方案1】:

给出错误“f 已声明但未使用”

f 在您的示例中是一个新声明的变量。它的范围位于if 块内,与最初在main() 开头声明的范围不同。

这是一个示例注释代码,可能有助于澄清(也可作为可运行的 Go Playground snippet):

package main

import (
    "fmt"
)

func main() {
    food := "burger"                 // (1) variable 'food' is declared
    fmt.Println("food is", food)     // OUTPUT: "burger"

    if true {
        food := "fries"              // (2) a new 'food' variable is a declared here. it shadows the one in (1)
        fmt.Println("food is", food) // this accesses the 'food' var from (2). OUTPUT: "fries"
    }

    fmt.Println("food is", food)     // this accesses the variable from (1). OUTPUT: "burger"
}

希望这有助于澄清。干杯,

【讨论】:

  • 感谢有道理。
【解决方案2】:

来自go-lang specification

与常规变量声明不同,短变量声明可以 重新声明变量,前提是 它们最初是在之前声明的 相同的块(如果该块是函数,则为参数列表 body) 具有相同的类型,并且至少有一个非空白变量 是新的

if 开始一个新块,因此这一行声明了一个名为 f 的新变量。

另一方面,= 运算符是一个赋值运算符,因此前一个作用域的值会被修改。

如果你想重复使用同一个变量,你可以显式声明err。

 var err error 
 f, err = strconv.ParseBool(m["READWRITE"])
 if err != nil {
    panic(err)
 }

【讨论】:

  • 我发现了。但是,我真的需要编写代码 - 我根据某些输入更改默认值(这恰好包括返回的错误 - 即 bar 函数)。所以我将不胜感激任何模式帮助
  • @AdmiralThrawn 编辑了一种可以实现这一目标的方式
【解决方案3】:

我为什么要这么说的背景:对于一个从很多其他语言迁移到 Go 的人来说,这将是一件奇怪的事情。

我在这里添加这个 - 只是为了证明显式使用临时变量可能很有用。 barNotCorrectYet,已使用 strconv.ParseBool 的“默认 false”返回更新 f(这将更改预设值)。因此,在我们想要忽略错误输入的情况下,将输出分配给临时变量,检查是否没有返回错误,然后更新预设值 barCorrectHandlingOfTempVariable 会很有用。

func barNotCorrectYet(m map[string]string) bool {
f := true // preset value of variable

if _, exists := m["READWRITE"]; exists {
    var err error

    fmt.Println("Before Updating f : ", f)

    f, err = strconv.ParseBool(m["READWRITE"])
    if err != nil {
        // If error, wrong value got updated on f.. and erased preset value
    }   

}

fmt.Println("[Value could be wrong] After Updating f : ", f)

return f
}

func barCorrectHandlingOfTempVariable(m map[string]string) bool {
f := true // preset value of variable

if _, exists := m["READWRITE"]; exists {

    fmt.Println("Before Updating f : ", f)

    temp, err := strconv.ParseBool(m["READWRITE"])
    if err != nil { // Update only when there are no errors to not affect preset value
        f = temp
    }       
}

fmt.Println("After Updating f : ", f)

return f
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    相关资源
    最近更新 更多