Предположим, у меня есть следующий код:
fun main() {
val userName: String? = "Dmitry" // line 1
userName?.takeLast(2)?.reversed() // line 2
userName?.plus("kotlin").plus("lang") // line 3
}
Я не могу понять причину использования оператора Элвиса раньше reversed() - почему нельзя использовать просто . ? Как я вижу в документе, takeLast() всегда предоставляет String, а не String?. Тот же сценарий работает для строки 3 в моем примере -> plus() всегда возвращает строку, поэтому Элвис перед вторым plus() не нужен?





Из характеристики:
a?.cточно так же, какwhen (val $tmp = a) { null -> null else -> { $tmp.c } }
Другими словами, userName?.takeLast(2)?.reversed() то же самое, что:
val $tmp1: String? = when (userName) {
null -> null
else -> userName.takeLast(2)
}
val $tmp2: String? = when ($tmp1) {
null -> null
else -> $tmp1.reversed()
}
// ...and so on.
Приведенное выше расширение показывает, что каждый шаг сам по себе может вернуться null, а значит, необходимо повторить ?..
Что касается .plus(), то первый .plus() — это String.plus() , тогда как второй .plus() — это String?.plus(). Последний будет рассматривать null как строку "null", но в случае с первым это не так.
Если userName — это null, userName.plus() позвонит String?.plus(). Только из-за ?. вместо этого вызывается String.plus(). Чтобы применить то же вышеупомянутое расширение:
val $tmp: String? = when (userName) {
null -> null
else -> userName.plus("kotlin") // String.plus()
}
$tmp.plus("lang") // String?.plus()
Поскольку перед ?. стоит takeLast(), результирующее выражение оценивается как строка, допускающая значение NULL. Поскольку userName может иметь значение null, takeLast() может даже не вызываться, и при вызове takeLast() у вас просто будет значение null.
В последней строке вы вызываете функцию расширения, определенную для приемника String, допускающего значение NULL, поэтому ее не нужно вызывать по условию. Он определен как fun String?.plus, поэтому его можно вызывать непосредственно на вводе, допускающем значение NULL.
Кстати, ?. не называется оператором Элвиса. Это называется оператором безопасного вызова. Оператор Элвиса — ?: и делает что-то другое.
Спасибо за примечание относительно именования операторов — я отредактировал заголовок. А еще спасибо за пояснения - теперь мне все понятно