Special Groovy magic re 属性 访问和集合/迭代?

Special Groovy magic re property access and collections / iterables?

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

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

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

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

我原以为会被解释为访问 methods 返回的 java.lang.reflect.Method[]name 属性,因此是一个错误。但它似乎工作。然后进行了更多实验,执行以下操作:

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

所以它看起来试图访问数组或列表的 属性(甚至可能 Iterable),实际上 returns 一个列表 属性 的每个元素列表(就像展开运算符一样)。

所以这让我想知道:

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

  2. 此行为是否仅适用于 'properties'(即遵循 getFoo() 命名约定的非参数方法)?这似乎是一些快速 Groovy 控制台测试的情况。

  3. 因此,在调用非getFoo() 样式方法或带参数的方法时,扩展运算符是否仅 necessary/useful? (因为你可以只使用 . 否则。)

更新:

似乎 spread *. 适用于任何 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 本身后来获得了同名的 属性,代码将开始返回那个(单个)属性 Iterable - 而不是来自元素的列表 属性 值。)

这是记录的 GPath 表达式(大约)here, and yes, it only works for properties. (There's an old blog post by Ted Naleid here 关于深入了解它在 2008 年的工作原理)

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

另请参阅:Groovy spread-dot operator

Better docs link(正如下面@NathanHughes 所指出的