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

Pau*_*aul 4 groovy

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

[].class.methods*.name
=> [add, add, remove, remove, get, ...
Run Code Online (Sandbox Code Playgroud)

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

[].class.methods.name
=> [add, add, remove, remove, get, ...
Run Code Online (Sandbox Code Playgroud)

我原以为要解释为访问返回的name属性,因此是一个错误.但似乎有效.然后进行了更多的实验,以下内容如下:java.lang.reflect.Method[]methods

[*[].class.methods].name
=> [add, add, remove, remove, get, ...
([].class.methods.toList()).name
=> [add, add, remove, remove, get, ...
Run Code Online (Sandbox Code Playgroud)

因此,似乎试图访问数组或列表的属性(甚至可能Iterable)实际上返回列表的每个元素的该属性的列表(如扩展运算符所示).

所以这让我想知道:

  1. 这种行为记录在哪里吗?(我在这里看不到它的例子:http://www.groovy-lang.org/operators.html并且在文档的其他地方没有看到它.)

  2. 此行为是否仅适用于"属性"(即遵循getFoo()命名约定的非arg方法)?这似乎是一些快速GroovyConsole测试的情况.

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

更新:

似乎传播*.适用于任何情况,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
Run Code Online (Sandbox Code Playgroud)

(我想这是一件好事:如果Iterable自己后来获得了一个具有相同名称的属性,代码将开始从Iterable- 而不是元素的list属性值返回该(单个)属性.)

tim*_*tes 5

这是在这里记录的GPath表达式(ish),是的,它只适用于属性.(Ted Naleid在这里发表了一篇关于如何在2008年开展工作的博客文章)

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

另请参见:Groovy扩展点运算符

更好的文档链接(正如@NathanHughes在下面指出的那样

  • 它也在http://docs.groovy-lang.org/latest/html/documentation/#gpath_expressions下记录,它似乎比第一个链接更彻底. (3认同)