Null Safety 

Null Safety 


В главное меню

Значение null подразумевает, что переменной не существует.  По умолчанию все типы в Kotlin не nullable и не могут хранить в себе значения null.

nullable элементы — (null возможен)

non-nullable — элементы (null не возможен)

Пример:

var signatureDrink = "Buttered Ale"
signatureDrink = null

Еще до запуска кода IntelliJ предупредит красным подчеркиванием, что что-то не так.

При запуске компилятор выдаст ошибку, т.к. переменная имеет тип, не поддерживающий null (строка, String). В Java такой вариант возможен, но свалится в исключение NullPointerException, которое остановит программу.

Код не может содержать null пока мы явно не укажем это:

var name: String? = null

? - оператор безопасного вызова. Эквивалентно проверке на null.

!! - оператор небезопасного вызова

Считается одним из сильных преимуществ языка. Во многих ЯП такой фичи нет. Позволяет на уровне компилятора выявить ошибку

Оператор Элвиса

Если мы хотим, чтобы значение не было null - добавляем оператор Элвиса ?:

Он означает, что если левая часть выражения равна null - выполняй правую часть.

var lenght = name.lenght? : 0

Null-безопасность

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

Для чего это вообще нужно?

П1: Есть функция, которая по логике программы должна возвращать NULL. В таком случае мы должны показать, что null хранится в переменной может.

Null-безопасность. Варианты

1. Оператор безопасного вызов

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

var beverage = readLine()?.replaceFirstChar { it.uppercaseChar() }

Когда компилятор встречает оператор безопасного вызова, он знает, что надо проверить значение на null. Обнаружив null, он пропустит вызов функции и просто вернет null.

Использование безопасного вызова с let

let — функция, которая возвращает результат лямбды

Пример №1:

var beverage = readLine()?.let {}

Если значение переменной отличается от null, выполняется лямбда (результат тела анонимной функции)


Let - пример

var name: String? = null

fun main() {
    if(name == null) {
        return
    }
    if (name.length > 5)
        println("fsf")
}

Будет ошибка на name, т.к. переменная глобальная и никто из другого потока не сможет обратиться к ней или изменить. Если глобальную name перенести в функцию все будет Ок.

Let позволяет использовать сравнение правильно. Если переменная = null, то правая часть выполняться не будет

fun main() {
 name?.let {
     if (it.length > 5) {
         println("Вывод")
     }
 }
}


Пример №2:

var name: String? = null

В данном случае мы предполагаем, что переменная может содержать null. В случае если захотим вычислить длину строки name.lenght - компилятор выдаст ошибку.

Решить проблему можно таким кодом:

if (name != null) {
  print (name.lenght)
}

Почему лучше использовать let а не сравнения?

1) Если используется глобальная переменная, в выражении на проверке компилятор не будет знать что там будет и подставит null. Появится ошибка, поэтому можно использовать let

name?.let {
  print (name.lenght)
}

let не запустился, а код не свалился в ошибку

2) Вместо того, чтобы создавать длинные цепочки выражений if-else, можно просто скомбинировать оператор («оператор безопасного вызова») с let: в результате мы получим лямбду, у которой аргумент it является не nullable-версией исходного объекта.


2. Оператор !!

Используется в случае если мы уверены, что переменная не будет null. В ином случае свалится в NullPointerException

var beverage = readLine()!!.capitalize()

3. Проверить значения на равенство null

В главное меню

Report Page