避免在Go语言中将返回两个值的函数与嵌套的连接词一起使用。

huangapple go评论81阅读模式
英文:

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

问题

这里,我有一个涉及返回两个值的一些函数的连词表达式:

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

我能否以某种方式避免嵌套?而不是嵌套,我能否将其写成一行表达式(在这种情况下,我无法完全中断或提前返回)?

英文:

Here, I have a conjunction expression involving some functions that return 2 values:

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

Could I somehow avoid the nesting? Instead of nesting, could I write this as an expression in one line (I can't quite break or return early in this case)?

答案1

得分: 2

使用一个辅助函数,你可以实现这个功能。

创建一个辅助函数,它返回第二个bool返回值,例如:

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

然后使用它:

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

请注意,这段代码与原始代码等效,因为&&运算符从左到右进行求值,并且它使用了短路求值:如果任何操作数求值为false,则不会调用后续操作数(函数)。

这个check()函数适用于所有返回两个值且第二个值为bool类型的函数(因为任何值都可以赋给interface{}类型的变量)。

这在规范:调用中有说明:

> 作为特例,如果函数或方法g的返回值与另一个函数或方法f的参数数量相等,并且可以逐个赋值给f的参数,则调用f(g(parameters_of_g))将在绑定g的返回值到f的参数后调用f。调用f除了调用g之外不能包含其他参数,而且g必须至少有一个返回值。如果f有一个最终的...参数,则它被赋予g的返回值,在赋值完普通参数后,剩余的返回值将被赋给它。

注意:由于check()中的第一个参数未使用,我们甚至可以在命名时使用下划线标识符,以明确表示我们不使用该参数:

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

With a helper function, you can.

Create a helper function which returns the second bool return value, e.g.:

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

And using it:

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

Note that this is equivalent to the original code because the && operator is evaluated from left to right and it is using short-circuit evaluation: if any of the operands evaluate to false, further operands (functions) will not be called.

This check() function works for all functions that return 2 values and the 2nd is of type bool (because any value can be assigned to a variable of type interface{}).

This is covered in the 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.

Note: since the first parameter in check() is not used, we can even use the blank identifier when naming it which will make it obvious that we don't use that parameter:

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

答案2

得分: 1

避免使用深层嵌套或过长的条件语句,可以通过使用函数来解决。例如,

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()
}
英文:

Avoid deep nesting or long conditionals running off the right side of the page with a function. For example,

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

huangapple
  • 本文由 发表于 2016年2月22日 15:33:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/35548073.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定