2013-06-03 108 views
5

在下面的代码中,x.test()返回[1,2]Groovy:参数相同,结果不同

因此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 

回答

0

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

实例的阵列具有size() == 2ArrayList count:伯爵作为一个参数,但它们包含两个元素

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

11

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

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 
2

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

x.test()声明为返回Object[]所以[1,2]的ArrayList将由return转换为两个元素的Object[]。因此y已经是Object[]并且不需要将其装入可变参数阵列中以传递给f

您需要打开y回到列表,或者通过改变test()返回类型或者说

f(y as List) 

相反,您可以使用传播操作

f(*z) // 2 

这将提取ArrayList的元素并将它们作为单独的参数传递给调用(然后像往常一样将其打包到可变参数数组中)。

相关问题