我对这两行编码感到困惑:
this.class.methods.name
这叫做Gpath(我是对的吗?)。现在考虑这段代码:
count = 0
def a = [1,2,3,4,5,5,51,2]
a.findAll { it == 5 }.each { count ++ }
println count
该行:
a.findAll { it == 5 }.each { count ++ }
被称为方法链接或Gpath?
从字面上看,我对这两个含义感到震惊。如果有人解释这两者之间的区别,那就太好了。
提前致谢。
答案 0 :(得分:3)
我不确定我是否正确理解了这个问题。
在我看来,在两个示例中,您使用方法链接,只是因为您正在调用另一个方法返回的对象中的方法。但是,正如Arturo mentions,有些人混淆了方法链和fluent interfaces。如果你想链接方法,一个流畅的界面确实非常方便。
但是,在Groovy中,您可以使用任何对象中的with
方法,而不是自己编写流畅的界面。例如,使用Arturo定义的相同Person
和Address
类,您可以执行以下操作:
def person = new Person()
person.with {
name = 'John'
age = 25
address = new Address('Boulevard St')
}
assert person.name == 'John' &&
person.age == 25 &&
person.address.name == 'Boulevard St'
现在,据我所知, GPath 只是一种访问对象属性的方法。例如,如果您有类:
class Foo {
def bar
}
Groovy中的GPath机制允许您执行以下操作:
def foo = new Foo(bar: 42)
assert foo.bar == 42
而不是使用getter访问bar属性,例如foo.getBar()
。没什么太花哨的。但是Groovy中的其他类也有一些GPath魔法,而且事情变得更有趣。例如,列表允许您以与访问普通属性相同的方式访问其元素中的属性:
def foos = (1..5).collect { new Foo(bar: it) } // Five Foos.
assert foos.bar == [1, 2, 3, 4, 5]
如您所见,访问具有该属性的对象列表上的bar属性将导致列表中包含该列表中每个对象的该属性的值。但是,如果您访问列表元素不具有的属性,例如foos.baz
,它会抛出一个MissingPropertyException。
这正是发生在:
this.class.methods.name
但是,我认为这种行为对我来说有点太神奇(除非你正在解析XML,在这种情况下完全没问题)。请注意,如果methods
方法返回的集合是一些具有name
属性的奇怪集合,methods.name
将导致该名称而不是集合中每个方法的名称。在这些情况下,我更喜欢使用(IMO)更明确的版本:
this.class.methods*.name
Wich会给你相同的结果,但它只是语法糖:
this.class.methods.collect { it.name }
...让表达的意图更加清晰(即“我想要methods
中每个方法的名称”)。
最后,这是非常偏离主题的代码:
count = 0
def a = [1,2,3,4,5,5,51,2]
a.findAll { it == 5 }.each { count ++ }
println count
可以改写为:
def a = [1,2,3,4,5,5,51,2]
def count = a.count { it == 5 }
println count
:)
答案 1 :(得分:2)
我认为您的代码是方法链的一个示例。
GPath是集成到Groovy中的路径表达式语言,允许在XML或POJO中导航。您可以在对象中执行嵌套属性访问。
Method chaining 是一种在面向对象的编程语言中调用多个方法调用的技术。每个方法都返回一个对象(可能是当前对象本身),允许在单个语句中将调用链接在一起。
我将使用TupleConstructor的示例来帮助创建对象。
import groovy.transform.TupleConstructor
@TupleConstructor
class Address {
String name
}
@TupleConstructor
class Person {
String name
Integer age
Address address
}
def person = new Person('John', 25, new Address('Boulevard St'))
好的,你是对的,这种访问称为GPath:
assert person.address.name == 'Boulevard St'
getter访问可以命名为方法链接:
assert person.getAddress().getName() == 'Boulevard St'
但如果我能做到这样的事情会发生什么:
person.setName('Louise')
.setAge(40)
.setAddress(new Address('Main St'))
我需要创建一个流畅的API,方法链接是方法,我们的想法是让方法返回this
而不是void
。
@TupleConstructor
class Person {
String name
Integer age
Address address
def setName(name) {
this.name = name
return this
}
def setAge(age) {
this.age = age
return this
}
}