已声明但未使用 - 如何更新 IF 语句中的变量

Declared and not used - How to update a variable in IF Statement

我正在尝试在 Go Lang 中设置一个具有默认值的 bool 变量并根据条件更新它。 func foo 编译,但是函数 bar 不编译并给出错误 "f declared and not used"

有一个related answer - 不能解释下一个问题

Go 中这个(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))
}

来自go-lang specification

Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new

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

另一方面,= 运算符是赋值运算符,因此修改了先前作用域中的值。

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

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

gives an error "f declared and not used"

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

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

我为什么这么说的背景:对于一个从许多其他语言转向 Go 的人来说,这会很奇怪。

我在这里添加这个 - 只是为了证明显式使用临时变量可能会有用。 barNotCorrectYet,已使用 strconv.ParseBool 中的 "default false" return 更新 f(这会更改预设值)。因此,在我们想要忽略错误输入的情况下,将输出分配给临时变量会很有用,检查是否没有错误 returned 然后更新预设值 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
}