Синтаксис и пунктуация в Groovy
Названия знаков по-английски и по-русски: Знаки препинания и символы в IT.
Синтаксис и пунктуация в Groovy
Groovy наследует пунктуацию Java, но добавляет правила для строк, замыканий и DSL. Ниже — то, что чаще всего путают при переходе с Java.
Сводка отличий от Java: Groovy и Java: совместимость. Операторы (?., ?:, ..<): операторы.
Кавычки и строки
| Форма | Интерполяция | Пример |
|---|---|---|
'...' | Нет | 'Hello, $name' → буквально $name |
"..." | Да (GString) | "Hello, $name" |
'''...''' | Нет, многострочно | SQL, XML-шаблон |
"""...""" | Да, многострочно | Отчёты, heredoc |
/.../ | Regex (slashy) | /\d+/ |
$/.../$ | Regex + интерполяция | $/id=${id}/$ |
В синтаксисе языка не используются типографские апострофы ’ — только ASCII ' и ".
def name = 'Alice'
println "Hello, $name" // Hello, Alice
println 'Hello, $name' // Hello, $name
Разбор:
def name = 'Alice'— переменная со строкой в одинарных кавычках: интерполяция отключена.println "Hello, $name"— GString в двойных кавычках:$nameзаменяется наAlice→ выводHello, Alice.println 'Hello, $name'— одинарные кавычки: символы$nameпечатаются как текст →Hello, $name.- Разница критична в логах и SQL: шаблоны с подстановкой — только
"..."или"""...""". - Комментарии
//в конце строки поясняют ожидаемый вывод при обучении.
Пример — вложенные GString и многострочный текст:
def javaStyleString = 'java String style'
def gStringStyle = "${javaStyleString}"
def literalDollar = '${javaStyleString}'
def bigGroovyString = """
${javaStyleString}
${gStringStyle}
"""
println bigGroovyString
Разбор:
'java String style'— обычный Java-совместимыйStringбез интерполяции."${javaStyleString}"— GString с подстановкой значения переменной.'${javaStyleString}'в одинарных кавычках — символы$и{остаются буквально.- Тройные двойные кавычки
"""..."""— многострочный GString с интерполяцией в каждой строке. println bigGroovyStringвыведет три строки с текстомjava String style.
Точка, запятая, скобки
- Точка
.— доступ к свойству или методу; у одноаргументных методов скобки часто опускают:println 'hi'. - Запятая
,— элементы списка, аргументы, именованные параметры:createUser name: 'Ann', age: 30. - Точка с запятой
;— разделитель на одной строке; в обычном Groovy-коде не обязательна.
def list = [1, 2, 3]
println list.size()
def x = 5; def y = 10; println x + y // допустимо, но редко
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример — начинается сdef list = [1, 2, 3]и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы методов и объявления функций задают основной шаг логики: входные значения передаются в метод и сразу обрабатываются.
- Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Замыкания (closures)
Блок { ... } — значение первого класса: его можно передать в метод.
def greet = { name -> "Hello, $name" }
assert greet('Bob') == 'Hello, Bob'
[1, 2, 3].each { println it } // it — неявный параметр
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сdef greet = { name -> "Hello, $name" }и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы методов и объявления функций задают основной шаг логики: входные значения передаются в метод и сразу обрабатываются.
- Поток выполнения строится на итерации: код последовательно применяет одну и ту же операцию к набору значений.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Скобки у вызова с замыканием последним аргументом можно опустить:
list.findAll { it > 0 }
// то же: list.findAll({ it > 0 })
Параметры в методы, замыкания и функции можно передавать без скобок у одноаргументных и некоторых многоаргументных вызовов:
def closureFunction = { a, b -> a + b }
println closureFunction 1, 2 // 3
// то же: closureFunction(1, 2)
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сlist.findAll { it > 0 }и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы функций или команд выполняют полезное действие: чтение данных, вычисление результата или запуск задачи сборки.
- Поток выполнения строится на итерации: код последовательно применяет одну и ту же операцию к набору значений.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Именованные аргументы
Пары ключ — значение без скобок — идиома Groovy (конструкторы, билдеры, Gradle):
def p = new Person(name: 'Alice', age: 30)
task copyDocs(type: Copy) {
from 'docs'
into 'build/docs'
}
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сdef p = new Person(name: 'Alice', age: 30)и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы методов и объявления функций задают основной шаг логики: входные значения передаются в метод и сразу обрабатываются.
- Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
switch
В Groovy switch принимает не только примитивы — классы, списки, регулярные выражения, замыкания (в зависимости от версии и стиля).
def status = 200
switch (status) {
case 200:
case 201:
println 'OK'
break
case 400..499:
println 'Client error'
break
default:
println 'Other'
}
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сdef status = 200и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы методов и объявления функций задают основной шаг логики: входные значения передаются в метод и сразу обрабатываются.
- Поток выполнения контролируется условиями: при разных состояниях кода выбирается соответствующая ветка и результат.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Регулярные выражения
def text = 'Order ID: 42'
assert text ==~ /Order ID: \d+/ // полное совпадение
def matcher = text =~ /(\d+)/
if (matcher) {
println matcher[0][1] // 42
}
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сdef text = 'Order ID: 42'и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы методов и объявления функций задают основной шаг логики: входные значения передаются в метод и сразу обрабатываются.
- Поток выполнения контролируется условиями: при разных состояниях кода выбирается соответствующая ветка и результат.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Подробнее: операторы.
Truthiness в условиях
В if и Elvis ?: "ложными" считаются — null, false, число 0, пустая строка '', пустые [] и [:].
def items = []
if (items) {
println 'has items' // не выполнится
}
def label = '' ?: 'default' // 'default'
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сdef items = []и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы методов и объявления функций задают основной шаг логики: входные значения передаются в метод и сразу обрабатываются.
- Поток выполнения контролируется условиями: при разных состояниях кода выбирается соответствующая ветка и результат.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Подчёркивание _
Как в Java/Kotlin:
- в числах:
1_000_000; - в циклах — "игнорируемый" параметр:
(1..5).each { _ -> println 'tick' }.
def million = 1_000_000
(1..3).each { _ -> println 'tick' }
Разбор:
1_000_000— литерал с разделителями разрядов (как в Java 7+); значение то же, что1000000.(1..3)— диапазон Groovy: включительно от 1 до 3; на каждой итерации closure получает номер, но_его игнорирует.println 'tick'выполнится три раза подряд.- Подчёркивание в параметре closure — соглашение "этот аргумент не нужен".
- Диапазоны часто используют в
switch(case 400..499) и в циклах вместоfor (int i = 0; ...).
Многострочные строки и Elvis
def sql = '''
SELECT id, title
FROM books
WHERE active = true
'''
def title = null
def label = title ?: 'Без названия'
println label
Разбор:
'''...'''— многострочная строка без интерполяции — удобно для SQL, XML, шаблонов.- Переносы и отступы внутри кавычек сохраняются в значении
sql. title ? — 'Без названия'— оператор Elvis — еслиtitle"ложный" (null,'',0,false), берётся правая часть.println labelвыведетБез названия, потому чтоtitleбылnull.- Для интерполяции в многострочнике используют
"""..."""с$переменные.
| и ||
| Оператор | Смысл | Короткое замыкание |
|---|---|---|
| | Побитовое OR; в условии — логическое OR без short-circuit | Нет — оба операнда вычисляются |
|| | Логическое OR | Да |
& / && | Аналогично для AND | && с short-circuit |
if (a() | b()) { } // вызовутся оба метода
if (a() || b()) { } // b() только если a() == false
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сif (a() | b()) { } // вызовутся оба методаи задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы функций или команд выполняют полезное действие: чтение данных, вычисление результата или запуск задачи сборки.
- Поток выполнения контролируется условиями: при разных состояниях кода выбирается соответствующая ветка и результат.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Словесные формы — and, or, not — то же, что &&, ||, !.
Связанные материалы
- Синтаксические конструкции — JSON/XML, фреймворки
- Ключевые слова