避免与 returns 2 值的函数一起嵌套?

Avoid nesting from conjunction with function that returns 2 values in go?

在这里,我有一个连词表达式,涉及一些 return 2 个值的函数:

if _, ok := f(); ok {
  if _, ok := g(); !ok {
    if h() {
      if _, ok := i(); ok {
        doStuff()
      }
    }
  }
}

我能以某种方式避免嵌套吗?除了嵌套,我可以将其写成一行中的表达式吗(在这种情况下,我不能完全中断或 return 过早)?

借助辅助函数,您可以。

创建一个辅助函数,其中 return 是第二个 bool return 值,例如:

func check(dummy interface{}, ok bool) bool {
    return ok
}

并使用它:

if check(f()) && check(g()) && h() && check(i()) {
    doStuff()
}

请注意,这与原始代码等效,因为 && 运算符是从左到右计算的,并且它使用 short-circuit evaluation:如果任何操作数计算为 false ,将不会调用进一步的操作数(函数)。

这个 check() 函数适用于 return 2 个值且第二个是 bool 类型的所有函数(因为任何值都可以分配给类型 interface{}).

这在Spec: Calls:

As a special case, if the return values of a function or method g are equal in number and individually assignable to the parameters of another function or method f, then the call f(g(parameters_of_g)) will invoke f after binding the return values of g to the parameters of f in order. The call of f must contain no parameters other than the call of g, and g must have at least one return value. If f has a final ... parameter, it is assigned the return values of g that remain after assignment of regular parameters.

注意:由于check()中的第一个参数没有使用,我们甚至可以在命名时使用空白标识符,这将很明显我们没有使用该参数:

func check(_ interface{}, ok bool) bool {
    return ok
}

避免深度嵌套或长条件 运行 关闭页面右侧的函数。例如,

package main

func f() (int, bool) { return 1, true }

func g() (int, bool) { return 1, true }

func h() bool { return true }

func i() (int, bool) { return 1, true }

func doStuff(f, g, i int) int { return f + g + i }

func andDoStuff() {
    ff, ok := f()
    if !ok {
        return
    }
    gg, ok := g()
    if !ok {
        return
    }
    if ok := h(); !ok {
        return
    }
    ii, ok := i()
    if !ok {
        return
    }
    doStuff(ff, gg, ii)

}

func main() {
    andDoStuff()
}