Home > Blockchain >  Should return err be put in else for if statement with declaration or avoid this style and outdent t
Should return err be put in else for if statement with declaration or avoid this style and outdent t

Time:12-29

In Go, we often write code with declaration in if statement and also return err. Like this:

    if res, err := getResult(); err != nil {
        return err
    } else {
        fmt.Println(res)
        // do something with res
    }

But the linter always tells me should drop the else block after return:

  ⚠  https://revive.run/r#indent-error-flow  if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)

The code snippet should looks like this to meet the suggestion:

    res, err := getResult()
    if err != nil {
        return err
    }
    fmt.Println(res)
    // do something with res

It seems that we should avoid to use the declaration in if statements.

So what is the correct Go style? And what should I do with the declaration in if statements?

CodePudding user response:

The section about if in Effective Go provides some guidance about this:

The code reads well if the successful flow of control runs down the page, eliminating error cases as they arise. Since error cases tend to end in return statements, the resulting code needs no else statements.

f, err := os.Open(name)
if err != nil {
  return err
}
d, err := f.Stat()
if err != nil {
  f.Close()
  return err
}
codeUsing(f, d)

If you adhere to this style, and if you intend to use the non-error results in your "happy path", you simply cannot declare the function's results as variables in the simple statement that can precede the condition of the if statement; you have no choice but to put that variable declaration before the if. However, in cases where the function only returns an error (or you don't care about its other results), you're free to put the variable declaration in the if:

// within some HTTP handler
var u User
dec := json.NewDecoder(w)
if err := dec.Decode(&u) {
   w.WriteHeader(http.StatusBadRequest)
   return
}
// use u

CodePudding user response:

From uber's go style guide code should reduce nesting as much as possible. For example:

if a {
    return a
} else {
    return b
}

is a bad way of writing code. Also this unnecessary else should be removed.

Also if you need the variables after the if block it's not necessary to declare them with if block. You may go through the uber's go style doc which will help you to write elegant go code.

CodePudding user response:

You can check official GO tutorial on flow control: https://go.dev/tour/flowcontrol/7

func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
    return v
} else {
    fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, though
return lim
}
  • Related