1. Введение
Давайте начнем с бытовой аналогии. Представьте себе рецепт:
Смешайте муку, яйца и сахар, взбейте, добавьте масло, взбейте еще раз.
Выглядит странно? А теперь представьте, что между словами «взбейте» и «добавьте» стоит запятая или скобки. Порядок действий сразу становится яснее.
В программировании похожая ситуация возникает, когда вы пишете сложное выражение:
val result = a > 0 && b < 10 || c == 3
Какой порядок? Что вычисляется первым: a > 0 && b < 10, потом || c == 3? Или всё наоборот?
Без четкого порядка вычислений компьютер может «перепутать ингредиенты», и ваш результат будет неожиданным.
2. Приоритет операторов в Kotlin
Kotlin (как и большинство языков программирования) использует определённую таблицу приоритетов операторов.
Операторы с более высоким приоритетом выполняются раньше, чем операторы с низким приоритетом.
Посмотрите на самую важную часть этой таблицы (для условных выражений):
| Оператор | Описание | Приоритет |
|---|---|---|
|
Скобки | самый высокий |
|
Логическое "НЕ" | высокий |
|
Равно / не равно | средний |
|
Сравнения | средний |
|
Логическое "И" | ниже |
|
Логическое "ИЛИ" | ещё ниже |
(Есть ещё арифметические операторы — они выше логических по приоритету.)
Главное правило
Операторы "И" (&&) имеют больший приоритет, чем "ИЛИ" (||),
то есть сначала будет вычислен "И", потом "ИЛИ". Недаром И — логическое умножение, а ИЛИ — сложение.
Блок-схема вычисления приоритета условий
graph LR
A["a > 0"] --&&--> B["b < 10"]
B --||--> C["c == 3"]
На практике: a > 0 && b < 10 || c == 3 — сначала считается a > 0 && b < 10, потом результат объединяется с c == 3 через ||.
3. Направление операторов: слева направо и наоборот
Кроме приоритета, есть ещё такое слово: ассоциативность. Это правило, в каком направлении вычисляются операторы, если они стоят «рядом» и имеют один приоритет.
Пример:
val a = true
val b = false
val c = true
val result = a && b && c
Вопрос: как посчитается?
Ответ: ассоциативность у && — слева направо.
Значит, сначала a && b, потом результат с c.
Применительно к условиям:
| Оператор | Ассоциативность |
|---|---|
|
слева направо |
|
справа налево |
4. Скобки — ваш лучший друг в сложных условиях
Вот здесь начинается магия (и спасение). Когда вы пишете выражение, скобки меняют приоритет и делают ваш код понятнее и безопаснее.
Пример 1 (без скобок):
val isAdult = age >= 18
val isCitizen = country == "Беларусь"
val hasPermit = hasSpecialPass == true
if (isAdult && isCitizen || hasPermit){
println("Доступ разрешён!")
}
Как считает Kotlin:
Сначала вычисляет isAdult && isCitizen, потом результат объединяет по || с hasPermit.
- Допустим, isAdult = true, isCitizen = false, hasPermit = true
- isAdult && isCitizen → true && false → false
- false || true → true
То есть, если у человека спецпропуск, всё равно пропустят.
А если без спецпропуска, но взрослый гражданин — тоже пропустят.
Пример 2 (со скобками):
if (isAdult && (isCitizen || hasPermit)) {
println("Доступ разрешён!")
}
Теперь программа сначала проверяет:
isCitizen || hasPermit, а затем этот результат вместе с isAdult.
То есть вам нужно быть взрослым и (или гражданином, или иметь спецпропуск).
Маленькая разница в скобках — огромная разница в логике!
5. Арифметика и сравнения в одном условии
Отдельная категория ошибок — когда в одном условии смешаны вычисления и сравнения. Kotlin-то разберётся, а вот человек может легко прочитать не так.
Например:
fun main() {
val x = 3
val y = 4
val limit = 10
val exceeds = x + y > limit
println(exceeds) // false
}
Это читается нормально, потому что у нас простой шаблон: «сумма больше лимита». Но представьте, что выражение усложняется:
fun main() {
val x = 3
val y = 4
val z = 5
val limit = 10
val ok = x + y * z > limit
println(ok) // true
}
Тут Kotlin сначала делает y * z, потом прибавляет x, потом сравнивает. Если вы хотели «сначала сложить x + y, потом умножить на z», то без скобок вы получите неверную логику. Исправление выглядит скучно, но честно:
fun main() {
val x = 3
val y = 4
val z = 5
val limit = 10
val ok = (x + y) * z > limit
println(ok) // true
}
Да, тут тоже true, но теперь хотя бы понятно, почему. А если поменять числа, разница быстро станет заметной — и именно такие «едва заметные» ошибки потом стоят времени.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ