1. Логический тип данных: Boolean
Как мы уже убедились, в Kotlin есть очень полезный оператор — if-else. Он выполняет один блок команд, если условие в скобках истинно, и второй блок команд, если условие ложно.
Чтобы было удобно работать с выражениями, которые могут быть истинными или ложными, в Kotlin добавили специальный тип — Boolean. Его главная особенность заключается в том, что переменные этого типа могут принимать всего два значения: true (истина) и false (ложь).
Никакие другие значения присвоить переменным типа Boolean невозможно. Компилятор не позволит.
Примеры переменных типа Boolean:
val isAdult: Boolean = true
val hasMoney: Boolean = false
У переменной типа Boolean всего два значения — true (истина) и false (ложь). Всё! Почти как у успешного теста — либо «прошёл», либо «упал» (ой).
2. Операции сравнения
И зачем же нужен такой примитивный тип? Реальная мощь Boolean проявляется, когда мы строим логические выражения. Обычно они получаются с помощью операторов сравнения.
| Оператор | Назначение | Пример | Значение |
|---|---|---|---|
|
Равно | |
true или false |
|
Не равно | |
true или false |
|
Больше | |
true или false |
|
Меньше | |
true или false |
|
Больше или равно | |
true или false |
|
Меньше или равно | |
true или false |
Пример:
val age = 20
val isAdult = age >= 18 // true (20 больше или равно 18)
val isTeenager = age >= 13 && age < 18 // false (20 не меньше 18)
val isEven = age % 2 == 0 // true (20 делится на 2 без остатка)
isAdult здесь станет true, потому что 20 – это действительно «взрослый» возраст.
Важный момент 1:
Операторы, состоящие из двух символов, разрывать нельзя. Т.е. такой код компилироваться не будет:
|
|---|
|
|
|
Важный момент 2:
Обратите внимание, что операторов => и =< нет: есть только <= и >=. Если вы напишете a =< 3, ваш код просто не скомпилируется.
Важный момент 3:
В Kotlin вы не можете записать выражение вида 18 < age < 65. Ведь у выражения 18 < age будет значение true или false. А сравнивать true < 65 (разные типы) нельзя. По крайней мере, в языке Kotlin.
3. Логические операции
В языке Kotlin нельзя записать выражение 18 < age < 65 — оно будет синтаксически некорректным и программа не скомпилируется.
Зато можно записать его так:
(18 < age) И (age < 65)
Разумеется, вместо слова И там будет другой логический оператор, и сейчас мы как раз поговорим о них подробнее.
В Kotlin есть три логических оператора: AND (и), OR (или) и NOT (не).
Хорошая новость: используя скобки, можно построить логические выражения любой сложности.
Плохая новость: разработчики Kotlin решили вместо слов and, or и not, использовать обозначения из языка C++.
Внимание на экран:
| Логический оператор | Ожидание | Реальность |
|---|---|---|
|
|
|
|
|
|
|
|
|
Вот несколько примеров использования логических операторов в Kotlin:
| Выражение | Расшифровка | Пояснение |
|---|---|---|
|
(0 < a) and (a < 100) | (0 < a) И (a < 100) |
|
(not a) and (not b) | (НЕ a) И (НЕ b) |
|
not((not a) or (not b)) | НЕ((НЕ a) ИЛИ (НЕ b)) |
4. Таблицы истинности
Вкратце пройдемся по логическим операциям.
Оператор AND
Оператор AND, он же И, он же &&, он же конъюнкция, он же логическое умножение.
| Выражение | Результат |
|---|---|
|
|
|
|
|
|
|
|
Другими словами, результат выражения равен true (истина) только если оба значения, которые участвуют в выражении, равны true (истина). В остальных случаях всегда false (ложь).
Оператор OR
Оператор OR, он же ИЛИ, он же ||, он же дизъюнкция, он же логическое сложение.
| Выражение | Результат |
|---|---|
|
|
|
|
|
|
|
|
Другими словами, результат выражения равен true (истина) всегда, если хотя бы одно значение, участвующее в выражении, равно true (истина). Если оба равны false, то результат false.
Оператор NOT
Оператор NOT, он же НЕ, он же !, он же инверсия.
| Выражение | Результат |
|---|---|
|
|
|
|
Меняет true на false и наоборот.
Полезные выражения:
| Выражение | Результат |
|---|---|
|
|
|
|
|
|
|
|
5. Примеры логических операций: and, or, not
Операция «И», AND, обозначается &&
Результат истина, только когда обе переменных истинны.
val age = 16
val hasTicket = true
val canAttend = age >= 14 && hasTicket // true (16 больше 14 И билет есть)
Если тебе есть 14 И у тебя есть билет — проходи!
Операция «ИЛИ», OR, обозначается (||)
Результат истина, если хотя бы одно условие истинно.
val isAdmin = false
val isModerator = true
val canEdit = isAdmin || isModerator // true (можно редактировать, если хоть что-то из этого true)
Если ты админ ИЛИ модератор — пожалуйста, нажимай кнопки!
Операция «НЕ», NOT, обозначается (!)
Инвертор превращает истину в ложь и наоборот.
val isWeekend = false
val shouldGoToWork = !isWeekend // true (если не выходные, работаем)
Если НЕ выходные — пора вставать!
Комбинирование: стройте условия какой угодно сложности
Можно комбинировать сколько угодно логических операций (желательно не перестараться, чтобы не получилось что-то вроде «если он не НЕ не НЕ не админ...»). Скобки можно (и нужно!) использовать для ясности.
Пример:
val age = 17
val hasTicket = false
val isVip = true
val canGo = (age >= 18 && hasTicket) || isVip // true, потому что isVip = true
В этом примере логика: если человек совершеннолетний и с билетом, или если он VIP — пропускаем. Если не VIP — только если взрослый и с билетом.
6. Короткое замыкание
Сейчас будет одна из самых практичных идей уровня. Логические операторы && и || в Kotlin работают так, что иногда вторая часть условия вообще не вычисляется. Это называется короткое замыкание (short-circuit).
Звучит как «проблема электрика», но на деле это суперполезный механизм. Он помогает писать условия безопасно: сначала проверяем «можно ли вообще делать следующую проверку», и только потом делаем потенциально опасные вычисления (например, деление). В результате мы избегаем ошибок типа «деление на ноль», причём не потому что мы ловим ошибку (исключения будут позже), а потому что не допускаем её.
Как это работает
Для A && B:
- если A уже false, весь результат точно false;
- значит B можно не вычислять вообще.
Для A || B:
- если A уже true, весь результат точно true;
- значит B тоже можно не вычислять.
Мини‑схема вычисления && и ||
flowchart TD
A[Вычислить левую часть A] --> B{Какой оператор?}
B -->|"&&"| C{"A == true?"}
C -->|"нет"| D[Результат false, B не вычисляем]
C -->|"да"| E[Вычислить правую часть B, результат = B]
B -->|"||" | F{"A == true?"}
F -->|"да"| G[Результат true, B не вычисляем]
F -->|"нет"| H[Вычислить правую часть B, результат = B]
Короткое замыкание на практике: защищаемся от деления на ноль
Самый классический пример, который реально спасает нервы новичкам: сначала проверить, что делитель не ноль, и только потом делить.
Правильный порядок: сначала безопасность, потом математика
fun main() {
val x = 0
if (x != 0 && (10 / x) > 1) {
println("Частное больше 1")
} else {
println("Либо x = 0, либо частное не больше 1") // Либо x = 0, либо частное не больше 1
}
}
Здесь происходит важная магия без магии: когда x == 0, выражение x != 0 даёт false, и Kotlin не вычисляет (10 / x) > 1. То есть деления на ноль не происходит вообще.
Неправильный порядок: опасная часть стоит первой
Если вы напишете наоборот — сначала деление, потом проверка x != 0 — короткое замыкание уже не поможет, потому что до него нужно «дожить». Правая часть не спасёт, если вы сломались в левой.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ