如何将两个返回参数合并为一个值?

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

How to combine two return params into one value

问题

我在代码中多次以不同版本出现:

func f() (bool, bool) {
   value, successFulOperation := someStuff()
   return value, successFulOperation
}

// 其他地方
value, successfulOperation := f()
if value && successfulOperation {
  // 做一些事情
}

只有当value为true且检索value的操作成功且没有错误时,才应执行// do stuff。换句话说:我不关心valuesuccessfulOperation,我只关心value && successfulOperation

我想要避免的解决方案(看起来冗长):

value, successfulOperation := f()
actualValue := value && successfulOperation
if actualValue {...} 

上面的代码非常简化。实际上,if条件将嵌套并且更加复杂。

我想要的是:

一个将两个值组合成一个值的f的包装器。我该如何做到这一点?解决方案应适用于任何接受任何参数并返回两个布尔值的函数。

以下代码不起作用:

type doubleBoolFunc func(...interface{}) (bool, bool)

func and(fn doubleBoolFunc, params ...interface{}) bool {
	b1, b2 := fn(params...)
	return b1 && b2
}

actualValue := and(f())
英文:

What I have many times in different versions in my code:

func f() (bool, bool) {
   value, successFulOperation := someStuff()
   return value, successFulOperation
}

// somewhere else
value, successfulOperation := f()
if value && successfulOperation {
  // do stuff
}

// do stuff should only be executed if value is true AND the operation that retrieved value succeeded without an error. In other words: I don't care about value or successfulOperation. I only care about value && successfulOperation.

A solution I want to avoid (seems verbose):

value, successfulOperation := f()
actualValue := value && successfulOperation
if actualValue {...} 

Above code is really simplified. In reality the if conditions will be nested and more complicated.

What I want:

A wrapper for f that combines both values into one. How do I do that? The solution should work for any function taking any parameters and returning two bools.

The following does not work:

type doubleBoolFunc func(...interface{}) (bool, bool)

func and(fn doubleBoolFunc, params ...interface{}) bool {
	b1, b2 := fn(params...)
	return b1 && b2
}

actualValue := and(f())

答案1

得分: 4

在Go语言1.18之前,你无法编写一个包装函数将这两个布尔值转换为一个布尔值。或者至少可以使用反射来实现,但会很混乱。

但是在Go语言1.17中,你可以这样编写:

func both(x, y bool) bool {
    return x && y
}

func f() (bool, bool) {
    return true, false
}

func main() {
    r := both(f())
    fmt.Println(r)
}

但更实际的做法(在我看来)是避免这种复杂性,使用一行if语句。并不是所有的东西都需要是一个函数或抽象化的:

if a, b := f(); a && b {
    ...
}

[1] 即使在Go语言1.18中引入了泛型,我认为也不会有一种方式来指定表示具有任意参数并返回两个布尔值的通用类型的方法。

英文:

You can't write a wrapper function to turn the two bools into one until generics are in the language in go 1.18<sup>1</sup>. Or at least you can, using reflect, but it's a mess.

But you can write this with go 1.17:

func both(x, y bool) bool {
    return x &amp;&amp; y
}

func f() (bool, bool) {
    return true, false
}

func main() {
    r := both(f())
    fmt.Println(r)
}

But more practical (in my opinion) is to eschew this complication, and use a 1-line if. Not everything needs to be a function or abstracted away:

if a, b := f(); a &amp;&amp; b {
    ...
}

<sup>[1]</sup> Even when generics are introduced in go 1.18, I don't think there'll be a way to specific a generic type that represents a function with arbitrary arguments that returns two bools.

答案2

得分: 0

func and(a, b bool) bool {
  return a && b
}

然后,如果f返回2个布尔值

value := and(f())

将会起作用。

英文:
func and(a, b bool) bool {
  return a &amp;&amp; b
}

then if f return 2 bool

value := and(f())

will work

答案3

得分: 0

要修复你问题末尾的代码,不要调用函数f(),只需引用函数名f,然后列出其参数:

// actualValue := and(f(args...))
actualValue := and(f, args...)

这里是一个示例链接。

英文:

To fix the code at the end of your question, don't invoke the function f(), simply reference the function name f and then list its args:

// actualValue := and(f(args...))
actualValue := and(f, args...)

https://go.dev/play/p/KAT2L58ZQy3

huangapple
  • 本文由 发表于 2021年12月29日 20:53:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/70519699.html
匿名

发表评论

匿名网友

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

确定