特殊的Groovy魔法重新属性访问和集合/迭代?

时间:2015-06-16 12:30:12

标签: groovy

我理解Groovy(2.4.3)中的扩展运算符*.在这里发生了什么:

[].class.methods*.name
=> [add, add, remove, remove, get, ...

但为什么离开*会产生相同的结果呢?

[].class.methods.name
=> [add, add, remove, remove, get, ...

我原本希望将其解释为访问name返回的java.lang.reflect.Method[]的{​​{1}}属性,因此会出错。但似乎有效。然后再进行一些实验,请执行以下操作:

methods

所以看起来试图访问数组或列表的属性(甚至可能是[*[].class.methods].name => [add, add, remove, remove, get, ... ([].class.methods.toList()).name => [add, add, remove, remove, get, ... )实际上会为列表的每个元素返回该属性的列表(如扩展运算符所示)。

所以这让我感到疑惑:

  1. 此行为是否记录在何处? (我在这里没有看到它的例子:http://www.groovy-lang.org/operators.html并且在文档的其他地方没有看到它。)

  2. 此行为是否仅适用于“属性”(即Iterable命名约定后的非arg方法)?一些快速的GroovyConsole测试似乎就是这种情况。

  3. 因此,当使用参数调用非getFoo()样式方法或方法时,扩展运算符是否只有必要/有用? (因为你可以只使用getFoo()。)

  4. 更新:

    似乎传播.适用于任何*.,而Iterable仅适用于集合。例如:

    .

    (我想这是一件好事:如果class Foo implements Iterable { public Iterator iterator() { [Long.class, String.class].iterator() } } (new Foo())*.name => [java.lang.Long, java.lang.String] (new Foo()).name => groovy.lang.MissingPropertyException: No such property: name for class: Foo 本身后来获得了一个具有相同名称的属性,代码将开始从Iterable返回该(单个)属性 - 而不是列出元素的属性值。)

1 个答案:

答案 0 :(得分:5)

GPath表达式记录(ish)here,是的,它仅适用于属性。 (关于如何在2008年开展工作,有一个古老的blog post by Ted Naleid here

对于方法,您需要使用*..collect()

另请参阅:Groovy spread-dot operator

Better docs link(由@NathanHughes指出