1

在 Go 中,我们经常在语句中编写带有声明的代码,if并且return err. 像这样:

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

但是 linter 总是告诉我应该在else之后删除块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)

代码片段应如下所示以满足建议:

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

看来我们应该避免在语句中使用if声明。

那么正确的 Go 风格是什么?我应该如何处理声明中的if声明?

4

3 回答 3

3

Effective Go 中about 部分if对此提供了一些指导:

如果成功的控制流顺着页面向下运行,则代码可读性很好,从而消除了出现的错误情况。由于错误情况往往以return语句结尾,因此生成的代码不需要else语句。

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

如果你坚持这种风格,并且如果你打算error在你的“幸福路径”中使用非结果,那么你根本不能在简单语句中将函数的结果声明为变量可以if在语句的条件之前;您别无选择,只能将该变量声明放在if. 然而,如果函数只返回一个error(或者你不关心它的其他结果),你可以自由地将变量声明放在if

// within some HTTP handler
var u User
dec := json.NewDecoder(w)
if err := dec.Decode(&u) {
   w.WriteHeader(http.StatusBadRequest)
   return
}
// use u
于 2021-12-28T16:23:08.033 回答
0

你可以查看官方的 GO 流量控制教程: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
}
于 2021-12-28T16:24:48.527 回答
0

uber 的 go 风格指南代码应该尽可能减少嵌套。例如:

if a {
    return a
} else {
    return b
}

是一种糟糕的代码编写方式。这个不必要的 else 也应该被删除。

此外,如果您需要 if 块之后的变量,则无需使用 if 块声明它们。你可以阅读 uber 的 go style 文档,它会帮助你编写优雅的 go 代码。

于 2021-12-28T16:16:08.717 回答