Статьи

Плавные операторы Groovy

smoothoperatpr Отправляйтесь в путешествие в 1984 году. Apple выпустит Macintosh , « Финальная битва » вот-вот начнется в V, и Шотландия выиграет Five Nations, завершив в этом турнире турнир. Прямо в разгар забастовки шахтеров в Великобритании английская поп-группа Sade выпустила броский номер: Smooth Operator . Это был успех на графике в Великобритании и США (не говоря уже о немецком, голландском и австрийском графиках). Мало что знал Сэйд, что спустя десятилетия язык программирования Groovy будет содержать несколько гладких операторов, которые выходят за рамки стандартного набора операторов Java. Теперь мы оставим сравнения 1980-х годов и обсудим некоторые из гладких операторов в Groovy в этом сообщении в блоге.

Элвис

Элвис Пресли-009 Оператор Элвиса (так назван в честь прически определенного человека) является сокращенной версией троичного оператора. Это очень удобно для нулевой проверки. И помните, хотя можно утверждать, что обработка нулей — плохая практика кодирования, потому что лучше не иметь нулей в вашем коде, многие API в кодовой базе неизбежно будут возвращать нули, и в реальном мире, где вы хотите добавить некоторую надежность и защитное кодирование для обеспечения бесперебойной работы, такого рода вещи могут быть полезны.

Теперь вот как это работает. Если выражение слева от оператора Элвиса оценивается как ложное ( помните, что в 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()

Оператор космического корабля

космос корабль Это происходит от языка программирования Perl и называется так, как вы уже догадались, <=> выглядит как космический корабль! Итак, как это работает? Ну, это так. Выражение слева и справа от оператора космического корабля оценивается. -1 будет возвращено, если операнд слева меньше, 0, если левый и правый равны, и 1, если левый больше. Его сила должна стать более очевидной на примере.

Скажем, у нас есть класс для представления разработчиков программного обеспечения.

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").name
assert "No name" == new RugbyPlayer().name
assert 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 1
methodRef('x') // outputs 2

. & Создает экземпляр org.codehaus.groovy.runtime.MethodClosure. Это может быть присвоено переменной и впоследствии вызвано, как показано.

Поздравляю всех вас с Новым Годом и, надеюсь, еще немного блогов в 2014 году.

Ссылка: Groovy’s Smooth Operators от нашего партнера JCG Алекса Стейвли в блоге Techlin в Дублине .