Шаг 23.
Основы Kotlin.
Условные конструкции. Условные операторы

    На этом шаге мы рассмотрим имеющиеся здесь условные операторы.

    В NyetHack может понадобиться проверить более сложные условия. Например, если игрок имеет благословение и его здоровье выше 50 или если игрок бессмертен, то вокруг него светится аура. В противном случае аура невидима.

    Можно использовать набор операторов if/else, чтобы определить, есть у игрока видимая аура или нет, но это приведет к большому количеству повторяющегося кода и отсутствию четко прослеживаемой логики условий. Есть более простой и понятный способ: использовать логические операторы в условии.

    Добавьте новую переменную и оператор if/else для вывода в консоль информации о наличии ауры.

fun main() {
    val name = "Madrigal"
    var healthPoints = 89
    val isBlessed = true
    val isImmortal = false

    // Аура
    if (isBlessed && healthPoints > 50 || isImmortal) {
        println("GREEN")
    } else {
        println("NONE")
    }
    .    .    .    .


Рис.1. Использование логических операторов в условии (Game.kt)

    Вы добавили значение val с именем isImmortal для хранения признака бессмертия игрока (доступно только для чтения, так как состояние смертности неизменно). Эта часть вам знакома, но появилось кое-что новое. Прежде всего, добавлен комментарий в коде, начинающийся с пары символов //.

    Все, что справа от //, - комментарий и игнорируется компилятором, поэтому в комментариях можно писать все что угодно. Комментарии очень полезны для организации и добавления информации о коде, что делает его более читабельным для других (или для вас в будущем, так как можно забыть некоторые детали кода).

    Далее, использованы два логических оператора внутри if. Логические операторы позволяют объединить операторы сравнения в одно длинное условие.

    && - оператор логического "И" ("and"). Требует, чтобы оба условия - слева и справа от него - были истинны, тогда все выражение будет истинно. || - оператор логического "ИЛИ" ("or"). Все выражение с этим оператором будет считаться истинным, если хотя бы одно из условий (или оба) справа или слева от него истинно.

    В таблице 1 перечислены логические операторы языка Kotlin.

Таблица 1. Логические операторы
Оператор Описание
&& Логическое "и": истинно, когда оба выражения истинны (иначе ложно)
|| Логическое "или": истинно, когда хотя бы одно выражение истинно (ложно, если оба ложны)
! Логическое "не": превращает истину в ложь и ложь в истину


Все операторы имеют приоритет, который определяет очередность их вычисления при объединении в выражение. Операторы с одинаковым приоритетом вычисляются слева направо. Операторы можно группировать, заключая в круглые скобки. Далее операторы перечислены в порядке убывания приоритета - от высокого к низкому:

    Возвратимся к NyetHack и разберем новое условие:

    if (isBlessed && healthPoints > 50 || isImmortal) {
        println("GREEN")
    }

    Или, читая по-другому: если игрок благословлен и у него больше 50 очков здоровья или если игрок бессмертен, то вокруг него светится зеленая аура. Мадригал не бессмертен, но благословлен и имеет 89 очков здоровья. А раз первое условие выполняется, то аура у Мадригала будет видна. Запустите программу, чтобы проверить, так ли это. Вы увидите:

  GREEN
  Madrigal has some minor wounds but is healing quite quickly!


Рис.2. Результат работы приложения

    Только подумайте, сколько вложенных условных операторов понадобилось бы, чтобы выразить эту логику без логических операторов. С помощью этих операторов можно выражать очень сложную логику.

    Код, определяющий наличие ауры, получился проще, чем если бы мы использовали набор операторов if/else, однако его можно сделать еще проще. Логические операторы можно применять не только в условных инструкциях, но также в обычных выражениях и даже в объявлении переменной. Добавьте новую булеву переменную, которая инкапсулирует условие видимости ауры, и выполните рефакторинг (то есть перепишите) условную инструкцию, использовав новую переменную.

fun main() {
    val name = "Madrigal"
    var healthPoints = 89
    val isBlessed = true
    val isImmortal = false

    // Аура
    val auraVisible = isBlessed && healthPoints > 50 || isImmortal
    if (auraVisible) {
        println("GREEN")
    } else {
        println("NONE")
    }
    .    .    .    .
Файл с проектом можно взять здесь.


Рис.3. Использование логических операторов в объявлении переменной (Game.kt)

    Вы записали результат проверки условия в новое значение val с именем auraVisible и изменили оператор if/else, чтобы он проверял это новое значение. Функционально этот код эквивалентен предыдущему, но вы выражаете правила через присваивание значения. Имя значения ясно отражает смысл правила в "человекочитаемом" виде: видимость ауры. Эта техника особенно полезна, когда правила становятся все более сложными, помогая понять логику работы будущим читателям вашего кода.

    Запустите программу снова, чтобы убедиться, что она работает как прежде. Вывод должен быть такой же.

    На следующем шаге мы рассмотрим условные выражения.




Предыдущий шаг Содержание Следующий шаг