2013-06-03 144 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的元素並將它們作爲單獨的參數傳遞給調用(然後像往常一樣將其打包到可變參數數組中)。

相關問題