Is it possible to make the following code to compile in Kotlin?
val variable: String? = "string"
val (a, b) = variable?.run {
1 to 2
}
Is it possible to make the following code to compile in Kotlin?
val variable: String? = "string"
val (a, b) = variable?.run {
1 to 2
}
The compiler does not allow destructuring because the expression on the right-hand side is typed as a nullable Pair<Int, Int>?
, and it's unclear what values a
and b
should get in case variable
is null.
To solve this, you need to get a not-null expression after =
.
There's a lot of different ways to deal with nullable values and produce a not-null value from a nullable one, see: In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them
For example, if you want to provide fallback values for a
and b
, then use the ?:
operator as follows:
val (a, b) = variable?.run {
1 to 2
} ?: (0 to 0)
An alternative, for example, would be to check variable
for null first:
val (a, b) = checkNotNull(variable) { "variable should never be null" }.run {
1 to 2
}
?: (null to null)
at the end and it worked, but I believe it could be done automatically. –
Landseer null as Int? to null as Int?
if you want a
and b
to be Int?
rather than Any?
. –
Jointed Null doesn't have any destructuring declarations. If you want a value of null to destructure like it's a pair of nulls, you could add these extensions:
operator fun <T> Pair<T, *>?.component1() = this?.component1()
operator fun <T> Pair<*, T>?.component2() = this?.component2()
Otherwise, as the other answer shows, you need to provide a default using the Elvis operator.
It's not automatic because it doesn't know what you want. Depending on what you're doing with it, 0 to 0
may be most appropriate, or maybe -1 to -1
or 0 to null
or null to null
.
null to null
. –
Landseer null to null
so it would work for any types. –
Jointed The question is, what do you want to do if your variable is null? If you want to throw an exception, go with require
or check
as @hotkey suggested.
However I have the case where I just want to return if the value is null. So I wrote myself a little helper function that allows for this:
private inline fun <T> T?.exitIfNull(exitBlock: () -> Nothing): T {
if (this == null)
exitBlock()
else
return this
}
You can call this function as follows:
val (a, b) = variable?.run {
1 to 2
}.exitIfNull {
return
}
A nice little use of the Nothing
keyword in Kotlin that I personally find quite fascinating
© 2022 - 2024 — McMap. All rights reserved.
a
andb
should be both null ifvariable
is null or I'm missing something?variable
is allowed to be null and the fallback values should be null in that case. – Landseer