我对这两行代码感到困惑:
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调用?
从字面上讲,我被这两种含义所震撼。如果有人能解释这两者之间的区别,那就太好了。
提前谢谢。
发布于 2012-02-05 06:10:42
我不确定我是否正确理解了这个问题。
在我看来,在这两个示例中,您都使用了方法链接,这仅仅是因为您正在调用由另一个方法返回的对象中的一个方法。但是,作为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而不是像foo.getBar()那样使用getter来访问bar属性。不要太花哨。但是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它会给你相同的结果,但它只是语法糖:
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:)
发布于 2012-02-05 05:02:29
我认为你的代码就是一个方法链接的例子。
是一种集成到Groovy中的路径表达式语言,它允许在XML或POJO中导航。您可以在对象中执行嵌套属性访问。
是一种在面向对象编程语言中调用多个方法调用的技术。每个方法返回一个对象(可能是当前对象本身),允许在单个语句中将调用链接在一起。
我将使用一个带有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访问可以命名为method chaining:
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
}
}https://stackoverflow.com/questions/9141804
复制相似问题