Я должен использовать двойной =
или тройной =
?
if(a === null) {
//do something
}
или
if(a == null) {
//do something
}
Аналогично для «не равно»:
if(a !== null) {
//do something
}
или
if(a != null) {
//do something
}
kotlin
kotlin-null-safety
пдева
источник
источник
Ответы:
Оба подхода генерируют один и тот же байт-код, поэтому вы можете выбирать все, что вам больше нравится.
источник
Структурное равенство
a == b
переводится какa?.equals(b) ?: (b === null)
Следовательно, при сравнении с
null
, структурное равенствоa == null
переводится в ссылочное равенствоa === null
.Согласно документам , нет смысла оптимизировать ваш код, поэтому вы можете использовать
a == null
иa != null
обратите внимание, что если переменная является изменяемым свойством, вы не сможете интеллектуально преобразовать ее в ее тип, не допускающий значения NULL внутри
if
оператора (потому что значение могло быть изменено другим потоком), и вам придется использоватьlet
вместо него безопасный оператор вызова .Оператор безопасного звонка
?.
a?.let { // not null do something println(it) println("not null") }
Вы можете использовать его в сочетании с оператором Элвиса.
Оператор Элвиса
?:
(я предполагаю, потому что знак допроса похож на волосы Элвиса)a ?: println("null")
И если вы хотите запустить блок кода
a ?: run { println("null") println("The King has left the building") }
Сочетание двух
a?.let { println("not null") println("Wop-bop-a-loom-a-boom-bam-boom") } ?: run { println("null") println("When things go null, don't go with them") }
источник
if
для нулевых проверок?a?.let{} ?: run{}
уместно только в редких случаях, иначе это не идиоматикаnull
проверок, я перечислял другие жизнеспособные варианты. Хотя я не уверен,run
есть ли какое-то снижение производительности. Я обновлю свой ответ, чтобы было понятнее.a
это avar
, то с использованиемa?.let{} ?: run{}
гарантии, что он будет правильно привязанlet
для всей области. Еслиa
естьval
, то разницы нет.val
, то использование let отличается, и это плохо. Я нашел эту статью очень хорошей для объяснения этого - Kotlin: не используйте LET только для проверки нуля .Kotlin способы обработки null
Безопасный доступ
val dialog : Dialog? = Dialog() dialog?.dismiss() // if the dialog will be null,the dismiss call will be omitted
Пусть функция
user?.let { //Work with non-null user handleNonNullUser(user) }
Ранний выход
fun handleUser(user : User?) { user ?: return //exit the function if user is null //Now the compiler knows user is non-null }
Неизменяемые тени
var user : User? = null fun handleUser() { val user = user ?: return //Return if null, otherwise create immutable shadow //Work with a local, non-null variable named user }
Значение по умолчанию
fun getUserName(): String { //If our nullable reference is not null, use it, otherwise use non-null value return userName ?: "Anonymous" }
Используйте val вместо var
val
доступен только для чтения,var
может изменяться. Рекомендуется использовать как можно больше свойств только для чтения, они ориентированы на многопоточность.Используйте lateinit
Иногда нельзя использовать неизменяемые свойства. Например, это происходит на Android, когда при
onCreate()
вызове инициализируется какое-то свойство . Для таких ситуаций в Kotlin есть языковая функция под названиемlateinit
.private lateinit var mAdapter: RecyclerAdapter<Transaction> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mAdapter = RecyclerAdapter(R.layout.item_transaction) } fun updateTransactions() { mAdapter.notifyDataSetChanged() }
источник
Дополнение к @Benito Bertoli,
комбинация на самом деле не похожа на if-else
"test" ?. let { println ( "1. it=$it" ) } ?: let { println ( "2. it is null!" ) }
Результат:
1. it=test
Но если:
"test" ?. let { println ( "1. it=$it" ) null // finally returns null } ?: let { println ( "2. it is null!" ) }
Результат:
1. it=test 2. it is null!
Также, если сначала использовать elvis:
null ?: let { println ( "1. it is null!" ) } ?. let { println ( "2. it=$it" ) }
Результат:
1. it is null! 2. it=kotlin.Unit
источник
Ознакомьтесь с полезными методами, они могут быть полезны:
/** * Performs [R] when [T] is not null. Block [R] will have context of [T] */ inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? { return input?.let(callback) } /** * Checking if [T] is not `null` and if its function completes or satisfies to some condition. */ inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{ return ifNotNull(this) { it.run(check) } ?: false }
Ниже приведен возможный пример использования этих функций:
var s: String? = null // ... if (s.isNotNullAndSatisfies{ isEmpty() }{ // do something }
источник