Pattern matching: синтаксис
В прошлый раз мы обсудили pattern matching в вакууме. Сегодня обсудим, как он выглядит в java с учётом 21 версии, и чего не хватает в текущей реализации.
Под зонтик pattern matching относят много фич: sealed классы, records, обновление switch и instanceOf. Sealed и records в контексте pattern matching — специфичные кейсы data oriented programming, не будем о них. Cфокусируемся на более популярных сценариях:)
Итак, как pattern matching воплощается в синтаксисе:
1️⃣ Компактный instanceOf
Раньше для неизвестного типа выполнялись две операции: instanceOf и явное приведение типа:
В логическом И можно использовать переменную в том же if:
✅
❌
У древнейшей конструкции доступен новый синтаксис:
▫️ Стрелочка вместо двоеточия
▫️ Break в конце case по умолчанию, и его можно не писать
▫️ Можно объединить несколько case в один
Старый синтаксис никуда не делся, им можно пользоваться:
🔥 Ответ на вопрос перед постом: выведется
3️⃣ Присвоение элемента через switch
Раньше в case принимались только константы. Теперь можно проверить тип переменной:
❌ Нет работы с массивами
Один из кейсов pattern matching — работа с набором данных, в которых мы ищем определённые признаки. Такого в java пока нет:
❌ Нет паттернов по полям класса
Под капот спрятан только instanceOf, остальные условия выглядят как в обычном if. Вся работа с полями происходит через методы:
Резюме
В текущем виде pattern matching выглядит слабо, особенно по сравнению с другими языками. Покрыты только базовые кейсы, в таком виде область применения очень ограничена.
Возможно это лишь промежуточный этап. Посмотрим, как фича будет развиваться и использоваться✨
В прошлый раз мы обсудили pattern matching в вакууме. Сегодня обсудим, как он выглядит в java с учётом 21 версии, и чего не хватает в текущей реализации.
Под зонтик pattern matching относят много фич: sealed классы, records, обновление switch и instanceOf. Sealed и records в контексте pattern matching — специфичные кейсы data oriented programming, не будем о них. Cфокусируемся на более популярных сценариях:)
Итак, как pattern matching воплощается в синтаксисе:
1️⃣ Компактный instanceOf
Раньше для неизвестного типа выполнялись две операции: instanceOf и явное приведение типа:
if (obj instanceof String) {Теперь эти операции объединены. Рядом с instanceOf объявляем имя переменной и сразу ей пользуемся:
String str = (String) obj;
// используем str
}
if (obj instanceof String str) {Тонкий момент— переменная определяется только при успешном выполнении instanceOf, поэтому есть нюанс с областью видимости.
// используем str
}
В логическом И можно использовать переменную в том же if:
✅
if (obj instanceof String s && s.length() > 5)
Логическое ИЛИ такого не позволяет, будет ошибка компиляции:❌
if (obj instanceof String s || s.length() > 5)
2️⃣ Компактный switchУ древнейшей конструкции доступен новый синтаксис:
▫️ Стрелочка вместо двоеточия
▫️ Break в конце case по умолчанию, и его можно не писать
▫️ Можно объединить несколько case в один
Старый синтаксис никуда не делся, им можно пользоваться:
switch (value) {В "новом стиле" это будет так:
case 1:
case 3: println("Odd"); break;
case 2:
case 4: println("Even"); break;
default: println("Other");
}
switch (value) {Важный момент — break добавляется по умолчанию только в вариант "со стрелочками". В "двоеточиях" break всё ещё добавляется вручную.
case 1,3 -> println("Odd");
case 2,4 -> println("Even");
default -> println("Other")
}
🔥 Ответ на вопрос перед постом: выведется
Even Other Even
. Чтобы работало как надо, нужно переписать на стрелочки или добавить break.3️⃣ Присвоение элемента через switch
int value = switch(…) {…};4️⃣ Проверка в switch по типам и сложные case
Раньше в case принимались только константы. Теперь можно проверить тип переменной:
switch (obj) {Если произошёл мэтч, для переменной сразу доступна доп. информация, и можно добавить условия в case:
case Integer i -> …
case Long l -> …
case Double d -> …
}
switch (response) {А теперь самое интересное! Обсудим, чего в текущей реализации нет:
case String s when s.length() == 10 -> …
}
❌ Нет работы с массивами
Один из кейсов pattern matching — работа с набором данных, в которых мы ищем определённые признаки. Такого в java пока нет:
double discount = switch(transaction) {В других языках такой функционал есть. Например, List patterns в С# или Matching sequences в питоне.
case ["vip", Long, _, _, Double sum] → sum*0,9
case _ → 0
}
❌ Нет паттернов по полям класса
Под капот спрятан только instanceOf, остальные условия выглядят как в обычном if. Вся работа с полями происходит через методы:
switch (figure) {В том же питоне запись гораздо компактнее:
case Square s when s.getLength() != 10 → …
}
match point:JEP Record Patterns мог быть как раз об этом, ведь records позиционируются как лаконичные контейнеры данных. Но увы.
case (0, 0): …
case (0, y): …
case _: …
Резюме
В текущем виде pattern matching выглядит слабо, особенно по сравнению с другими языками. Покрыты только базовые кейсы, в таком виде область применения очень ограничена.
Возможно это лишь промежуточный этап. Посмотрим, как фича будет развиваться и использоваться✨