【问题标题】:Groovy: same parameters, different resultsGroovy:相同的参数,不同的结果
【发布时间】:2013-05-29 06:12:42
【问题描述】:

在下面的代码中,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

【问题讨论】:

    标签: groovy


    【解决方案1】:

    问题在于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)Integer.valueOf(2) 的ArrayList。因此,当您调用 f([1,2])Groovy 时,Groovy 会创建一个包含此 ArrayList 作为其唯一项的单元素数组,并将该数组作为闭包参数传​​递。

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

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

      f(y as List)
      

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

      f(*z) // 2
      

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

      【讨论】:

        【解决方案3】:

        y[Ljava.lang.Object 的实例,而 [1,2]zArrayList 的实例

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-16
          • 1970-01-01
          相关资源
          最近更新 更多