In the below code, x.test()
returns [1,2]
.
So y = [1,2]
.
Yet f([1,2])
prints 1
, but f(y)
prints 2
.
How do I write f(y)
so it prints 1
?
Perversely, f(z)
prints 1
, even though z = y
.
def f = { Object... args -> println args.size(); };
class Test { Object[] test() { return [1,2]; } }
def x = new Test();
def y = x.test();
def z = [1,2];
f([1,2]); // 1
f(y); // 2
f(z); // 1
== is symmetric in groovy. While that table is super handy, it's a bit misleading as == isn't actually on it.
In groovy, the ==~ operator (aka the "match" operator) is used for regular expression matching. != is just a plain old regular "not equals".
In Groovy we use the == operator to see if two objects are the same, in Java we would use the equals() method for this. To test if two variables are referring to the same object instance in Groovy we use the is() method. The !=
The problem is that y
and z
, while they appear to be the same, are actually of different types. y
is an Object[]
while z
is an ArrayList<Integer>
. Groovy handles arrays and lists differently, automatically coercing the former into a varargs parameter list, but not the latter.
println y.getClass(); // class [Ljava.lang.Object
println z.getClass(); // class java.util.ArrayList
As for a solution to your problem, either change your test()
to return a List
instead of an array:
class Test { List test() { return [1,2]; } }
or manually coerce the array into a list when you pass it to f
:
f(y as List); // 1
The expression [1,2]
in Groovy denotes an ArrayList with two members, Integer.valueOf(1)
and Integer.valueOf(2)
. Thus when you call f([1,2])
Groovy creates a single-element array containing this ArrayList as its only item, and passes that array as the closure argument.
But x.test()
is declared to return Object[]
so the [1,2]
ArrayList will be converted to a two element Object[]
by the return
. Thus y
is already an Object[]
and does not need to be boxed up in a varargs array to be passed to f
.
You need to turn y
back into a list, either by changing the return type of test()
or by saying
f(y as List)
Conversely, you can use the spread operator
f(*z) // 2
which will extract the elements of the ArrayList and pass them as individual arguments to the call (which will then be packaged up into a varargs array as usual).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With