Groovy:相同的参数,不同的结果

时间:2013-06-03 06:13:03

标签: groovy

在下面的代码中,x.test()会返回[1,2]

所以y = [1,2]

然而f([1,2])打印1,但f(y)打印2

如何撰写f(y)以便打印1

不正常,f(z)打印1,即使是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

3 个答案:

答案 0 :(得分:11)

问题是yz虽然看起来是相同的,但实际上是不同类型的。 yObject[]zArrayList<Integer>。 Groovy以不同的方式处理数组和列表,自动将前者强制转换为varargs参数列表,而不是后者。

println y.getClass(); // class [Ljava.lang.Object
println z.getClass(); // class java.util.ArrayList

至于问题的解决方案,请更改test()以返回List而不是数组:

class Test { List test() { return [1,2]; } }
当您将数组传递给f时,

或手动将数组强制转换为列表:

f(y as List); // 1

答案 1 :(得分:2)

Groovy中的表达式[1,2]表示包含两个成员Integer.valueOf(1)Integer.valueOf(2)的ArrayList。因此,当您调用f([1,2])时,Groovy会创建一个包含此ArrayList作为其唯一项的单元素数组,并将该数组作为闭包参数传​​递。

但声明x.test()返回Object[],因此[1,2] ArrayList将被Object[]转换为两个元素return。因此y已经是Object[],并且不需要在varargs数组中装箱以传递给f

您需要将y更改回列表,方法是更改​​test()的返回类型或说

f(y as List)

相反,您可以使用 spread 运算符

f(*z) // 2

将提取ArrayList的元素并将它们作为调用的单独参数传递(然后将照常将其打包到varargs数组中)。

答案 2 :(得分:0)

y[Ljava.lang.Object的一个实例,而[1,2]z的实例是ArrayList

数组将size() == 2ArrayList计数作为一个参数,但它们包含两个元素

Groovy会为你做一些类型转换;)