Я не уверен, правильно ли я понял вопрос.
Как я вижу, в обоих примерах вы используете цепочку методов просто потому, что вы вызываете метод в объекте, который возвращается другим методом. Но, как Артуро упоминает , некоторые люди путают цепочку методов и плавные интерфейсы . Свободный интерфейс действительно очень удобен, если вы хотите объединить методы.
В Groovy, однако, вы можете вместо того, чтобы самостоятельно кодировать свободный интерфейс, использовать метод with
в любом объекте. Например, используя те же классы 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
}
Механизм GPath в Groovy позволяет выполнять следующие действия:
def foo = new Foo(bar: 42)
assert foo.bar == 42
Вместо того, чтобы обращаться к свойству 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
, который даст вам тот же результат, но это всего лишь синтаксический сахар для:
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
:)