Шаг 75.
Основы Kotlin.
Null-безопасность и исключения. Исключения. Проверка условий

    На этом шаге мы перечислим функции, которые могут использоваться для организации проверки на null.

    Неожиданные значения могут заставить программу вести себя непредсказуемо. Вам придется потратить много времени, проверяя достоверность входных значений, чтобы убедиться, что вы работаете с задуманными значениями. Некоторые источники исключений тривиальны, например неожиданные значения null. В стандартной библиотеке Kotlin есть пара удобных функций, упрощающих проверку и отладку входных данных. Они позволяют возбудить исключение с произвольным сообщением.

    Эти функции называются функциями проверки условий, потому что позволяют объявить условия, которые должны быть соблюдены до выполнения кода.

    Например, в предыдущих шагах вы увидели несколько вариантов защиты от NullPointerException и других исключений. Последний вариант - это использование функции проверки условий, такой как checkNotNull, которая проверяет значение на null и возвращает его, если оно не равно null, а иначе возбуждает IllegalStateException. Попробуйте заменить возбуждение UnskilledSwordJugglerException вызовом функции проверки условий.

fun main() {
    var swordsJuggling: Int? = null
    val isJugglingProficient = (1..3).shuffled().last() == 3
    if (isJugglingProficient) { swordsJuggling = 2 }
    
    try {
         proficiencyCheck(swordsJuggling)
        swordsJuggling = swordsJuggling!!.plus(1)
    } catch (e: Exception) {
        print(e)
    }
   
    println("You juggle $swordsJuggling swords!")
}

fun proficiencyCheck(swordsJuggling: Int?) {
    checkNotNull(swordsJuggling, { "Player cannot juggle swords" })
}

class UnskilledSwordJugglerException() :
        IllegalStateException("Player cannot juggle swords")
Файл с проектом можно взять здесь.


Рис.1. Использование функции проверки условий (SwordJuggler.kt)

    Функция checkNotNull проверяет равенство swordsJuggling значению null после определенной точки в коде. Если checkNotNull получит null, она возбудит IllegalStateException, сообщая о недопустимости текущего состояния. Функция checkNotNull принимает два аргумента:

    Функции проверки условий - хороший способ проверить требования, прежде чем выполнять код. Они гораздо понятнее, чем ручное возбуждение исключений, потому что проверяемое условие можно видеть в имени функции. В этом случае конечный результат не меняется: либо swordsJuggling будет иметь значение, отличное от null, либо в консоли появится сообщение об ошибке, но использование checkNotNull позволяет получить более ясный код, чем возбуждение UnskilledSwordJugglerException вручную.

    В стандартной библиотеке Kotlin есть пять функций проверки условий; это разнообразие отличает их от других вариантов проверки на null. Пять функций проверки условий перечислены в таблице 1.

Таблица 1. Функции с предварительными условиями
Функция Описание
checkNotNull Возбуждает IllegalStateException, если аргумент null. В противном случае возвращает полученное значение
require Возбуждает IllegalArgumentException, если условие не выполняется
requireNotNull Возбуждает IllegalArgumentException, если аргумент null. В противном случае возвращает полученное значение
error Возбуждает IllegalArgumentException с указанным сообщением, если аргумент null. В противном случае возвращает полученное значение
assert Возбуждает AssertionError, если условие не выполняется и на этапе компиляции установлен флаг, разрешающий проверку утверждений во время выполнения


Проверка утверждений здесь не рассматривается. Для получения подробной информации см. https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/assert.html.

    Функция require (требуется) реализует весьма полезную проверку. Функции могут использовать require, чтобы определить граничные значения для передаваемых им аргументов. Посмотрите на функцию, использующую require, чтобы явно задать требования к параметру swordsJuggling:

fun juggleSwords(swordsJuggling: Int) {
    // Жонглировать
    require(swordsJuggling >= 3, { "Juggle at least 3 swords to be exciting." }) 
}

    Чтобы устроить настоящее шоу, игрок должен жонглировать хотя бы тремя мечами. Используя require в начале объявления функции, мы четко даем понять это любому, кто пожелает вызвать juggleSwords.

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




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