JavaRush /Курсы /Kotlin SELF /Приоритет операторов и скобки в условиях

Приоритет операторов и скобки в условиях

Kotlin SELF
3 уровень , 4 лекция
Открыта

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 && isCitizentrue && falsefalse
  • false || truetrue

То есть, если у человека спецпропуск, всё равно пропустят.
А если без спецпропуска, но взрослый гражданин — тоже пропустят.

Пример 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, но теперь хотя бы понятно, почему. А если поменять числа, разница быстро станет заметной — и именно такие «едва заметные» ошибки потом стоят времени.

1
Задача
Kotlin SELF, 3 уровень, 4 лекция
Недоступна
Магия скобок
Магия скобок
1
Задача
Kotlin SELF, 3 уровень, 4 лекция
Недоступна
Логический щит
Логический щит
1
Задача
Kotlin SELF, 3 уровень, 4 лекция
Недоступна
Реклама и запреты
Реклама и запреты
1
Задача
Kotlin SELF, 3 уровень, 4 лекция
Недоступна
Порог тревоги
Порог тревоги
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ