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, але тепер принаймні зрозуміло, чому. А якщо змінити числа, різниця швидко стане помітною. Саме такі «ледь помітні» помилки потім і забирають час.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ