Как запустить код, если объект нулевой?
В Kotlin я могу запустить код, если объект не является нулевым, как это:
data?.let {
... // execute this block if not null
}
но как я могу выполнить блок кода, если объект нулевой?
10 ответов
Просто используйте нормальный if
:
if (data == null) {
// Do something
}
Вы можете использовать операторelvis и оценить другой блок кода с помощью run { ... }
:
data?.let {
// execute this block if not null
} ?: run {
// execute this block if null
}
Но это, кажется, не так легко читается, как простой if
-else
заявление.
Кроме того, вы могли бы найти этот Q&A полезным:
Вот краткий синтаксис с использованием оператора Элвиса. Напомним, что оператор Элвиса выполняет только правую сторону, если левая сторона оценивается как ноль.
data ?: doSomething()
Вы можете создать инфиксную функцию следующим образом:
infix fun Any?.ifNull(block: () -> Unit) {
if (this == null) block()
}
Тогда вы можете сделать это:
data ifNull {
// Do something
}
Вы можете использовать ниже код
myNullable?.let {
} ?: {
// do something
}()
также вы можете опустить fun()
myNullable?.let {
} ?: fun() {
// do something
}()
или вы можете позвонить invoke()
вместо ()
myNullable?.let {
} ?: fun() {
// do something
}.invoke()
Обратите внимание, что возвращаемое значение отличается, как показано ниже.
val res0 = myNullable?.let {
} ?: () {
}()
val res1 = myNullable?.let {
} ?: fun() {
"result"
}()
val res2 = myNullable?.let {
} ?: () {
"result"
}()
println("res0:$res0")
println("res1:$res1")
println("res2:$res2")
РЕЗУЛЬТАТ:
res0:kotlin.Unit // () {} with empty
res1:kotlin.Unit // fun() {}
res2:result // () {} with return
let также может применяться к null, независимо от того, является ли объект нулевым или нет:
data.let {d->
if (d != null){
// execute this block if data is not null
} else {
// for data is null
}
}
Обычно это делается с помощью следующих языковых конструкций:
data?.also {
// execute this block if not null
} ?: run {
// execute this block if null
}
будь осторожен с
data?.let {
// execute this block if not null
// but careful, returning null accidenatlly will execute run {} as well.
null
} ?: run {
// execute this block if null
}
Блок let может случайно вернуть нулевую переменную, и блок run также будет выполнен.
Если вам не нравятся конструкцииalso
иrun
вы можете изменить имя на что-то вроде ниже:
inline fun <T> T?.ifNotNull(block: (T) -> Unit): T? {
if (this != null) {
block(this)
}
return this
}
inline fun <T> T.elseIfNull(block: () -> Unit) {
if (this == null) { block() }
}
и используйте так:
class A
var a1: A? = null
var a2: A? = A()
a1.ifNotNull {
println("a1 is Not Null: $it")
}.elseIfNull {
println("Is null do something else")
}
a2.ifNotNull {
println("a2 is Not Null $it")
}.elseIfNull {
println("Is null do something else")
}
Вышеуказанная гарантия, что второй блок не будет выполнен, если верхний случайно вернет ноль.
Я предпочитаю это решение,
fun runIfNull(any: Any?, block: () -> Unit) {
if (any == null) block()
}
Что вы используете как:
runIfNull(any) { // it will run; }
Он имеет преимущество по сравнению с ответом @Dmitry Ryadnenko, где можно запутаться и использовать его неправильно.
У вас есть функция
infix fun Any?.ifNull(block: () -> Unit) {
if (this == null) block()
}
И в случае, если вы используете его для нулевого объекта следующим образом:
nullObject?.ifNull { // THIS WILL NOT BE CALLED }
nullObject.ifNull { // this will be called }
Блок не будет выполняться.
Обратите внимание на ошибочно добавленный вопросительный знак "?"
Следующий ответ - более простая версия этого ответа.
Функция возвращает действительный список, если цепочка вызовов успешна,
иначе
возвращается
emptyList()
class A(var b: B? = null)
class B(var c: C? = null)
class C(var d: D? = null)
class D(var list: List<String>?)
//1. Note ? in A?.<functionName>
fun A?.isNull(): List<String> {
if(this == null) { // 2. access object using this keyword
return emptyList<String>()
}
return this.b?.c?.d?.list ?: emptyList<String>()
}
fun main() {
//1. Empty A object
var a: A? = A()
println(a.isNull()) //[]
//2. Null A object
a = null
println(a.isNull()) //[]
//3. All Valid chaining parameters
val d = D(listOf("d"))
val c = C(d)
var b : B? = B(c)
a = A(b)
println(a.isNull()) //[d]
//4. Invalid chain parameter
b = null
a = A(b)
println(a.isNull()) //[]
}
Еще один хороший вариант использования when
:
when(myVariable){
null -> {
// execute your null case here
}
else -> { // non null case }
}
when
довольно универсален, поэтому вы можете указать точные условия, включая нулевой регистр.