Home > Software engineering >  How to combine two return params into one value
How to combine two return params into one value

Time:12-30

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

CodePudding user response:

You can't write a wrapper function to turn the two bools into one until generics are in the language in go 1.181. 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 && 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 && b {
    ...
}

[1] 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.

CodePudding user response:

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

then if f return 2 bool

value := and(f())

will work

CodePudding user response:

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

  • Related