首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gpath和链接方法到底是什么?

Gpath和链接方法到底是什么?
EN

Stack Overflow用户
提问于 2012-02-04 23:07:08
回答 2查看 767关注 0票数 0

我对这两行代码感到困惑:

代码语言:javascript
复制
this.class.methods.name

这就是所谓的Gpath (对吗?)。现在考虑这段代码:

代码语言:javascript
复制
count = 0
def a = [1,2,3,4,5,5,51,2]
a.findAll { it == 5 }​.each { count ++ }
println count

这行代码:

代码语言:javascript
复制
a.findAll { it == 5 }​.each { count ++ }

是作为方法链调用还是Gpath调用?

从字面上讲,我被这两种含义所震撼。如果有人能解释这两者之间的区别,那就太好了。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-05 06:10:42

我不确定我是否正确理解了这个问题。

在我看来,在这两个示例中,您都使用了方法链接,这仅仅是因为您正在调用由另一个方法返回的对象中的一个方法。但是,作为Arturo mentions,有些人混淆了方法链和fluent interfaces。如果你想链接方法,一个流畅的接口确实非常方便。

然而,在Groovy中,您可以在任何对象中使用with方法,而不是自己编写流畅的接口。例如,使用Arturo定义的相同PersonAddress类,您可以执行以下操作:

代码语言:javascript
复制
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只是访问对象属性的一种方式。例如,如果您有这样的类:

代码语言:javascript
复制
class Foo {
    def bar
}

Groovy中的GPath机制允许您执行以下操作:

代码语言:javascript
复制
def foo = new Foo(bar: 42)
assert foo.bar == 42

而不是像foo.getBar()那样使用getter来访问bar属性。不要太花哨。但是Groovy中的其他类也有一些GPath的魔力,在那里事情变得更有趣。例如,列表允许您以与访问普通属性相同的方式访问其元素中的属性:

代码语言:javascript
复制
def foos = (1..5).collect { new Foo(bar: it) } // Five Foos.
assert foos.bar == [1, 2, 3, 4, 5]

正如您所看到的,访问具有该属性的对象列表上的bar属性将生成一个列表,其中包含列表中每个对象的该属性值。但是如果你访问一个列表元素没有的属性,比如foos.baz,它将抛出一个MissingPropertyException。

这正是正在发生的事情:

代码语言:javascript
复制
this.class.methods.name

但是,我认为这种行为对我来说有点太神奇了(除非您正在解析XML,在这种情况下完全没问题)。请注意,如果methods方法返回的集合是某个具有name属性的奇怪集合,则methods.name将生成该名称,而不是该集合中每个方法的名称。在这些情况下,我更喜欢使用(IMO)更明确的版本:

代码语言:javascript
复制
this.class.methods*.name

它会给你相同的结果,但它只是语法糖:

代码语言:javascript
复制
this.class.methods.collect { it.name }

..。让我们更清楚地了解表达式的意图(即“我想要methods中每个方法的名称”)。

最后,这是相当离题的代码:

代码语言:javascript
复制
count = 0
def a = [1,2,3,4,5,5,51,2]
a.findAll { it == 5 }​.each { count ++ }
println count

可以重写为:

代码语言:javascript
复制
def a = [1,2,3,4,5,5,51,2]
def count = a.count { it == 5 }
println count

:)

票数 3
EN

Stack Overflow用户

发布于 2012-02-05 05:02:29

我认为你的代码就是一个方法链接的例子。

是一种集成到Groovy中的路径表达式语言,它允许在XML或POJO中导航。您可以在对象中执行嵌套属性访问。

是一种在面向对象编程语言中调用多个方法调用的技术。每个方法返回一个对象(可能是当前对象本身),允许在单个语句中将调用链接在一起。

我将使用一个带有TupleConstructor的示例来帮助创建对象。

代码语言:javascript
复制
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:

代码语言:javascript
复制
assert person.address.name == 'Boulevard St'

getter访问可以命名为method chaining:

代码语言:javascript
复制
assert person.getAddress().getName() == 'Boulevard St'

但是如果我可以这样做会发生什么呢:

代码语言:javascript
复制
person.setName('Louise')
      .setAge(40)
      .setAddress(new Address('Main St'))

我需要创建一个流畅的API,方法链接是一种方式,其想法是让方法返回this而不是void

代码语言:javascript
复制
@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
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9141804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档