71

I want to return multiple values from a function written in groovy and receive them , but i am getting an error

class org.codehaus.groovy.ast.expr.ListExpression, with its value '[a, b]', is a bad expression as the left hand side of an assignment operator

My code is

int a=10
int b=0
println "a is ${a} , b is ${b}"
[a,b]=f1(a)
println "a is NOW ${a} , b is NOW ${b}"

def f1(int x) {   
  return [a*10,a*20]
}
1

3 Answers 3

126

You almost have it. Conceptually [ a, b ] creates a list, and ( a, b ) unwraps one, so you want (a,b)=f1(a) instead of [a,b]=f1(a).

int a=10
int b=0
println "a is ${a} , b is ${b}"
(a,b)=f1(a)
println "a is NOW ${a} , b is NOW ${b}"

def f1(int x) {
    return [x*10,x*20]
}

Another example returning objects, which don't need to be the same type:

final Date foo
final String bar
(foo, bar) = baz()
println foo
println bar

def baz() {
    return [ new Date(0), 'Test' ]
}

Additionally you can combine the declaration and assignment:

final def (Date foo, String bar) = baz()
println foo
println bar

def baz() {
    return [ new Date(0), 'Test' ]
}
Sign up to request clarification or add additional context in comments.

4 Comments

Added a line to the answer to highlight the change the OP needed to make since different brackets in 8 lines of code can be easily missed.
If the return types are object, then what will happen? Can anyone explain please. I want to return multiple object from a method.
It's pretty much the same. I'll add an example with dates.
The more technically correct and common term for what Justin wrote above as "unwraps" is "destructuring"; in this case, the calling statements are destructuring assignment statements. See 1.2.1. Multiple assignment for details.
48

You can declare and assign the variables in which the return values are stored in one line like this, which is a slightly more compact syntax than that used in Justin's answer:

def (int a, int b) = f1(22)

In your particular case you may not be able to use this because one of the variables passed to f1 is also used to store a return value

2 Comments

According to Groovy Goodness you don't even need the int declarations inside the parentheses.
@sschuberth True, but you might want it if you want the static type checking/coercion that comes with declaring types
6

When running Groovy in the context of Jenkins pipeline job the above answers do not work (at least on version 2.60.2), but the following does:

node {
    obj = ret2()
    fw = obj[0]
    lw = obj[1]
    echo "fw=${fw}"
    echo "lw=${lw}"
}

def ret2()
{
    return [5, 7]
}

Or alternatively:

node {
    obj = ret2()
    fw = obj.a
    lw = obj.b
    echo "fw=${fw}"
    echo "lw=${lw}"
}

def ret2()
{
    return [a:5, b:7]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.