Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Интервалы

В Kotlin есть уникальные типы, которые вы не встречали в Java. Уверен, вам понравится.

Интерфейс ClosedRange<T> с методом rangeTo() позволяет быстро и элегантно создавать интервалы от начального до конечного значения, который является частью диапазона. На его основе созданы специальные типы IntRange, LongRange, CharRange.

Метод rangeTo() имеет операторную форму .. и может сопровождаться операторами in и !in.

Рассмотрим простой пример.


val oneToFive = 1..5
println(oneToFive::class.java) // возвращает class kotlin.ranges.IntRange

Альтернативная версия, которой вы вряд ли будете пользоваться.


val oneToFive: IntRange = 1.rangeTo(5)

Тип IntRange и его родственники имеют сверхспособности - проходить циклически по всем элементам. И это очень удобно.

Мы уже знакомились с оператором in в цикле for. Но он может быть использован и отдельно в функции. Например, мы можем проверить, входит ли символ в диапазон символов русского алфавита от символа к до символа т. Символ о точно попадёт в заданный диапазон, а также символы Л, М, Н и т.д.


fun isCat(c: Char) = c in 'к'..'т' || c in 'К'..'Т'
// проверяем символы в нижнем и верхнем регистрах
println(isCat('о'));

Интервалы помогают сократить количество кода и улучшить читаемость.


// много кода
if (i >= 0 && i <= 10)
    println(i)

// меньше кода
if (i in 0..10)
    println(i)

По умолчанию, интервалы увеличиваются от меньшего к большему. Если нужно изменить порядок, то используйте downTo. Если нужно изменить шаг, то используйте ключевое слово step. Примеры показаны в for.

until

Очень часто в циклах встречается выражение size - 1, чтобы не выйти за пределы массива. Можно заменить на until, чтобы не использовать последний элемент интервала. Примеры показаны в for.

Функции для работы с интервалами

В Kotlin есть несколько готовых функций для работы с интервалами. Например, coerceIn(), вы задаёте интервал, если число не входит в него, то берётся минимальное или максимальное значение интервала.


fun showProgress(progress: Int){
    val percent = progress.coerceIn(0, 100)
    println("We're ${percent}% done")
}

showProgress(45)  // 45
showProgress(105) // 100

Progression

Несколько классов для интервалов позволяют работать с элементами интервала просто и быстро. Пример для класса IntProgression.


val progression: IntProgression = 0..100 step 10
for (i in progression) {
    println(i)
}
/*
0
10
20
30
40
50
60
70
80
90
100
*/

Указав нужный интервал, можно перечислить его элементы в обратном порядке через метод reversed():


val fate: IntRange = 1..9
for (life in fate.reversed()) {
    println("Remaining lives: " +
            "$life")
}

Получим ответ.


Remaining lives: 9
Remaining lives: 8
Remaining lives: 7
Remaining lives: 6
Remaining lives: 5
Remaining lives: 4
Remaining lives: 3
Remaining lives: 2
Remaining lives: 1
Реклама