英文:
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()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论