Допускающие null и ненулевые типы
Маркер типа ?.
«Допускающие null и ненулевые типы» — бесплатный урок Android Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 4 уроков всего.
Почему важна безопасность null
Многие сбои в приложениях Android происходят из-за одной ошибки: использования значения, которого на самом деле нет. В других языках это приводит к печально известной ошибке NullPointerException во время выполнения.
Kotlin предотвращает такую проблему на этапе компиляции. Система типов отслеживает, какие значения могут быть null, а какие никогда им быть не могут. В этом уроке Вы познакомитесь с основами этой системы.
Типы, не допускающие null
По умолчанию тип Kotlin не может содержать null. String всегда ссылается на настоящую строку.
Если попытаться присвоить ему null, код даже не скомпилируется. Это безопасное поведение по умолчанию.
fun main() {
val name: String = "Ada"
println(name.length)
}Null отклоняется
Посмотрите, что произойдёт при попытке поместить null в тип, не допускающий null.
Компилятор немедленно остановит Вас. До выполнения программы скрытая ошибка не дойдёт.
val name: String = null // Compile error:
// Null can not be a value of a non-null type StringТипы, допускающие null, с ?
Иногда значение действительно может отсутствовать, например необязательное второе имя пользователя. Чтобы разрешить это, добавьте ? к типу.
String? может содержать настоящую строку или null. Вопросительный знак обозначает тип, допускающий null.
fun main() {
val middleName: String? = null
println(middleName)
}Два разных типа
String и String? — это разные типы. Второй является более широким типом и включает значение null.
Именно это различие позволяет компилятору защищать Вас. Он точно знает, где может появиться null.
val sure: String = "hello"
val maybe: String? = "hello"
// maybe could later be null; sure never canНельзя напрямую использовать тип, допускающий null
Компилятор не позволит вызвать метод у значения, допускающего null, без предварительной проверки.
Поскольку middleName может быть равно null, обращение к .length вызовет ошибку компиляции. Необходимо обработать случай с null.
val middleName: String? = null
println(middleName.length)
// Error: only safe (?.) or non-null (!!) calls allowedПроверка с помощью if
Самый простой способ использовать значение, допускающее null, — проверить его условием if.
В ветви, где Вы доказали, что значение не равно null, Kotlin автоматически рассматривает его как тип, не допускающий null, поэтому .length работает.
fun main() {
val text: String? = "Kotlin"
if (text != null) {
println(text.length)
}
}Интеллектуальное приведение типов
После успешной проверки на null компилятор запоминает, что значение не равно null, до конца этого блока. Это называется интеллектуальным приведением типа.
Вам не пришлось выполнять преобразование вручную. Kotlin автоматически отследил это за Вас.
fun describe(s: String?) {
if (s == null) return
// s is now treated as String here
println("Length is " + s.length)
}Параметры функций
Допускает ли параметр значение null — это часть контракта функции. Параметр, не допускающий null, обещает вызывающему коду, что никогда не получит null.
Параметр, допускающий null, сообщает, что отсутствие входных данных ожидается и обрабатывается.
fun greet(name: String) {
println("Hi, " + name)
}
// greet(null) would not compileВозвращаемые типы могут допускать null
Функция может вернуть null, чтобы сообщить, что ничего не найдено. Обозначьте её возвращаемый тип с помощью ?.
Тогда вызывающий код знает, что результат нужно проверить перед использованием.
fun firstChar(s: String): Char? {
if (s.isEmpty()) return null
return s[0]
}По умолчанию не допускайте null
Хорошее правило: отдавайте предпочтение типам, не допускающим null. Добавляйте ? только тогда, когда значение действительно может отсутствовать.
Так код остаётся честным. Чем меньше у Вас типов, допускающих null, тем меньше проверок на null потребуется позже.
// Prefer this:
val score: Int = 0
// Over this, unless null is meaningful:
val maybeScore: Int? = nullБыстрая проверка
Проверьте, насколько хорошо Вы понимаете типы, допускающие и не допускающие null.
Итоги
Типы Kotlin по умолчанию не допускают null и отклоняют null на этапе компиляции. Добавьте ?, чтобы сделать тип допускающим null, если значение может отсутствовать.
Нельзя напрямую использовать значение, допускающее null. Проверка на null интеллектуально приводит его к типу, не допускающему null, и позволяет безопасно его использовать. Далее Вы изучите более короткие способы работы со значениями, допускающими null.
Часто задаваемые вопросы
Урок «Допускающие null и ненулевые типы» бесплатный?
Да — полный текст урока «Допускающие null и ненулевые типы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 4 уроков всего.
Чему я научусь в уроке «Допускающие null и ненулевые типы»?
Маркер типа ?. Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Android Academy?
Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Допускающие null и ненулевые типы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Android Academy?
Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Допускающие null и ненулевые типы
- Безопасные вызовы и Elvis
- Функции let, also и области видимости
- Как избежать NullPointerExceptions