
Элвис

Теперь вот как это работает. Если выражение слева от оператора Элвиса оценивается как ложное ( помните, что в Groovy есть несколько вещей, таких как нуль, например, пустая строка, которую можно принудительно указать как ложное) , результатом выражения будет то, что включено право.
|
1
|
String country = country.name ?: "Unknown country" |
Итак, в приведенном выше примере, если country.name имеет значение null или просто «поскольку оба значения в Groovy имеют значение false, страна будет назначена как« Неизвестная страна ». Если country.name не было ложным, стране было бы просто присвоено это значение.
Null-Safe разыменование (также называемое оператором безопасной навигации)
Это особенно полезно, чтобы избежать исключений нулевого указателя в цепочечном выражении. Например,
|
1
|
String location = map.getLocation().getXandYCoordinates(); |
может привести к исключению нулевого указателя. Но используя оператор безопасной навигации, если либо map, либо результат map.getLocation () равны нулю
|
1
|
String location = map?.getLocation()?.getXandYCoordinates(); |
местоположение будет просто установлено как ноль. Таким образом, исключение нулевого указателя не выдается.
Распространение
Оператор Spread полезен при выполнении метода для элементов коллекции и получении результата. В этом примере я анализирую несколько строк в массивах, а затем запускаю замыкание на каждом из массивов, чтобы получить все первые элементы.
|
1
2
3
|
def names = ["john magoo","peter murphy"]def namesAsArrays = names*.split(" ")namesAsArrays.each(){print it[0]} |
Теперь запомните, что оператор Spread может использоваться только для методов и элементов. Например, он не может выполнить закрытие. Но мы можем использовать возможности метапрограммирования Groovy для создания метода, а затем использовать оператор распространения для его вызова. Предположим, у нас был список чисел, которые мы тоже хотели добавить к 50, а затем умножить ответ на 6, что мы могли бы сделать:
|
1
2
3
|
def numbers = [43,4]java.lang.Integer.metaClass.remixIt = {(delegate + 50) * 6}numbers*.remixIt() |
Оператор космического корабля

Скажем, у нас есть класс для представления разработчиков программного обеспечения.
|
01
02
03
04
05
06
07
08
09
10
11
|
class SoftwareEngineer { String name int age String toString() { "($name,$age)" }}def engineers = [ new SoftwareEngineer(name: "Martin Fowler", age: 50), new SoftwareEngineer(name: "Roy Fielding", age: 48), new SoftwareEngineer(name: "James Gosling", age: 58)] |
Теперь мы можем легко отсортировать по возрасту
|
1
|
engineers.sort{it.age} |
Но что будет, когда наш список инженеров будет расти и расти, и у нас будет несколько инженеров одного возраста? В этих сценариях было бы неплохо отсортировать по возрасту первое и назвать второе. Мы могли бы достичь этого, выполнив:
|
1
2
|
engineers.sort{a, b -> a.age <=> b.age ?: a.name <=> b.name |
Это выражение попытается отсортировать инженеров по возрасту в первую очередь. Если их возраст равен a.age <=>, то b.age вернет 0. В Groovy и в конструкции Elvis 0 означает ложь, и, следовательно, a.name <=> b.name будет оценено и использовано для определения Сортировать.
Доступ к полю
В Groovy при попытке доступа к полю Groovy вызовет соответствующий метод доступа. Оператор доступа к полю — это механизм, заставляющий Groovy использовать доступ к полю.
|
1
2
3
4
5
6
7
8
|
class RugbyPlayer { String name String getName() {name ?: "No name"} }assert "Tony" == new RugbyPlayer(name: "Tony").nameassert "No name" == new RugbyPlayer().nameassert null == new RugbyPlayer().@name |
Справочник по методам
Оператор Method Reference позволяет вам рассматривать ссылку на метод как замыкание.
|
1
2
3
4
5
6
7
8
|
class MyClass { void myMethod() { println "1" } void myMethod(String s) { println "2" }}def methodRef = new MyClass().&"myMethod"methodRef() // outputs 1methodRef('x') // outputs 2 |
. & Создает экземпляр org.codehaus.groovy.runtime.MethodClosure. Это может быть присвоено переменной и впоследствии вызвано, как показано.
Поздравляю всех вас с Новым Годом и, надеюсь, еще немного блогов в 2014 году.