Урок 4. Условия if и when
До сих пор программы выполняли все строки по порядку. Но часто нужно выбрать: если число отрицательное — одно действие, иначе — другое. Для этого в Kotlin есть if и when.
if и else
fun main() {
val t = readln().toInt()
if (t < 0) {
println("Frost")
} else if (t < 15) {
println("Cool")
} else {
println("Warm")
}
}7CoolКак это читается:
if (условие) { ... }— блок в фигурных скобках выполняется, только если условие верно;else if (условие)— следующая проверка, если предыдущие не подошли; таких может быть сколько угодно;else— что делать, если не подошло ничего. Он необязателен.
Проверки идут сверху вниз, и выполняется только первый подходящий блок. При t = 7 первое условие 7 < 0 неверно, второе 7 < 15 верно — выводится Cool, а до else дело не доходит.
Если в блоке одна команда, фигурные скобки можно опустить: if (t < 0) println("Frost"). Но со скобками меньше ошибок, когда команд потом становится больше.
Сравнения
| Знак | Значение |
|---|---|
== | равно |
!= | не равно |
<, > | меньше, больше |
<=, >= | меньше или равно, больше или равно |
Сравнение — тоже значение: 5 > 3 — это true, его можно положить в переменную типа Boolean.
Строки сравниваются тем же ==, и сравнивается их текст: answer == "yes". В Java для этого нужен был equals, в Kotlin — нет. Сравнить без учёта больших и маленьких букв: answer.equals("yes", ignoreCase = true).
Одиночный = — присваивание, а не сравнение. Строка if (x = 5) в Kotlin не соберётся, так что эту ошибку компилятор поймает сам.
И, или, не
Условия соединяют логическими операциями:
&&— «и»: верно, если верны оба условия;||— «или»: верно, если верно хотя бы одно;!— «не»: меняетtrueнаfalseи наоборот.
fun main() {
val year = 2024
val leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0
println(leap)
val age = 15
if (age >= 7 && age <= 17) {
println("School age")
}
if (!leap) {
println("Not a leap year")
}
}true
School ageГод високосный, если делится на 4, но не на 100, — или если делится на 400. 2024 делится на 4 и не делится на 100, поэтому leap — true, и последняя строка не выводится.
if как выражение
В Kotlin if не только выбирает действие, но и возвращает значение — то, которым кончается выбранная ветка. Его можно сразу положить в переменную:
fun main() {
val a = 12
val b = 30
val max = if (a > b) a else b
println(max)
val parity = if (a % 2 == 0) "even" else "odd"
println("$a is $parity")
}30
12 is evenТернарного оператора условие ? a : b, как в Java и C, в Kotlin нет — его место занимает if. Когда if даёт значение, ветка else обязательна: иначе непонятно, что положить в переменную.
when
Когда вариантов много, цепочка else if становится длинной. Вместо неё удобен when — он сравнивает значение с вариантами по очереди:
fun main() {
val day = 6
val name = when (day) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
4 -> "Thursday"
5 -> "Friday"
6, 7 -> "Weekend"
else -> "No such day"
}
println(name)
}Weekend- слева от
->— вариант, справа — результат или действие; - несколько вариантов пишут через запятую:
6, 7 ->; else— всё остальное;- как и
if,whenвозвращает значение. В этом случае веткаelseнужна, если варианты перечислены не все: иначе компилятор сообщит, чтоwhenдолжен охватывать все случаи (exhaustive).
Вариантом может быть диапазон — in 90..100 значит «от 90 до 100 включительно» (о диапазонах — в следующем уроке):
fun main() {
val score = 87
val grade = when (score) {
in 90..100 -> "A"
in 75..89 -> "B"
in 60..74 -> "C"
else -> "F"
}
println(grade)
}Bwhen без значения
Если после when не писать значение в скобках, в каждой ветке стоит своё условие — получается аккуратная замена цепочки if – else if:
fun main() {
val x = -5
when {
x > 0 -> println("positive")
x < 0 -> println("negative")
else -> println("zero")
}
}negativeЗдесь when не возвращает значение, а выполняет действие, поэтому else мог бы и не стоять. Ветки проверяются сверху вниз, выполняется первая подходящая.
Частые ошибки
- Порядок условий: в цепочке
if (score > 50) … else if (score > 90) …вторая ветка не выполнится никогда — любое число больше 90 уже подошло под первое условие. Сначала проверяйте более узкое условие. - Сравнение дробных чисел через
==:0.1 + 0.2 == 0.3— этоfalse, потому что дробные числа хранятся приближённо. Сравнивайте разницу с малым числом:abs(a - b) < 1e-9(функцияabsподключается строкойimport kotlin.math.abs). - Двойное сравнение, как в математике:
if (1 < x < 10)не соберётся —1 < xуже даётtrueилиfalse, а их с числом не сравнить. Пишитеx > 1 && x < 10или, если границы входят,x in 1..10.
Коротко
if (условие) { ... } else if (...) { ... } else { ... }— выполняется первый подходящий блок.- Сравнения:
==,!=,<,>,<=,>=; строки сравниваются по тексту через==. - Логика:
&&— и,||— или,!— не. ifиwhenвозвращают значение:val max = if (a > b) a else b. Тернарного оператора нет.when (x) { 1 -> …; 2, 3 -> …; in 4..10 -> …; else -> … }.