Does the first nullcheck make sense here?
error.timeoutInSeconds != null -> {
error.timeoutInSeconds?.let {
doWithNonNullTimeout(it)
} ?: doWithNull("Timeout is null")
}
When I am not wrong, the second statement
doWithNull("Timeout is null")
is never being reached?
CodePudding user response:
This branch will only be called if timeoutInSeconds
is non-null, so why would you expect doWithNull
to ever be called? By the way, the ?.let {} ?: …
pattern is error prone and should not be used as an alternative to if/else. Because if the last expression of your lambda happens to evaluate to null, then both branches are run. ?.also
would be safer, but is less readable than if/else. Example:
foo.bar?.let {
someBarFunction() // maybe it returns null as a side-effect
} ?: doSomethingAssumingBarIsNull()
// in this case, both someBarFunction() and doSomethingAssumingBarIsNull() are called
When working with a mutable nullable property or nullable property from another class you can do one of these to do it safely:
foo.bar.let { bar ->
if (bar != null) {
// use smart-cast not-null bar
} else {
// do something when bar is null
}
}
// or
val bar = foo.bar
if (bar != null) {
// use smart-cast not-null bar
} else {
// do something when bar is null
}
// or this, but I don't think it's as readable as either of the above
foo.bar?.also {
// use not-null it
} ?: // do something when bar is null
Not sure what to suggest as your alternative because it’s not clear why you would have tried to handle a null case in a branch of your when
where you already know it’s not null.