Объявлено и не используется - Как обновить переменную в операторе IF - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь установить переменную bool со значением по умолчанию и обновить ее на основе условия в Go Lang.Func foo компилируется, но функция bar не компилируется и выдает ошибку "f объявлен и не используется"

Существует ответ - что не объясняет следующий вопрос

Каков правильный шаблон для этого (функция бара) в Go?

Вот код:

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

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

выдает ошибку "f объявлен и не используется"

f в вашем образце является вновь объявленной переменной.Его область действия находится в блоке if и отличается от той, которая была первоначально объявлена ​​в начале вашего main().

. Вот пример кода с комментариями, который может помочь прояснить (также доступен как работающий GoДетская площадка фрагмент ):

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

Надеюсь, это поможет прояснить ситуацию.Cheers,

0 голосов
/ 24 октября 2018

Контекст о том, почему я это называю: для человека, переходящего на Go с нескольких других языков, это было бы странно.

Я добавляю это здесь - просто чтобы продемонстрировать, что это может бытьполезно использовать временную переменную явно.barNotCorrectYet, имеет f, обновляемый с возвращением «false по умолчанию» из strconv.ParseBool (который изменил бы заданное значение).Таким образом, в случаях, когда мы хотим игнорировать неверные входные данные, будет полезно назначить выходные данные для временной переменной, проверить, не было ли ошибок возвращено, а затем обновить предустановленное значение 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
}
0 голосов
/ 24 октября 2018

Из спецификация go-lang

В отличие от обычных объявлений переменных, краткое объявление переменных может переопределять переменные при условии , что они были первоначально объявлены ранее в том же блоке (или список параметров, если блок является телом функции) того же типа, и по крайней мере одна из непустых переменных является новой

if начинает новый блок и, следовательно,эта строка объявляет новую переменную с именем f.

С другой стороны, оператор = является оператором присваивания, и поэтому значение из предыдущей области видоизменяется.

Если вы хотите повторно использовать эту же переменную, вы можете объявить err явно.

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