Reputation: 113
I have a method which returns an array, on with I check that a certain index is set. In Java, I would do:
if (obj.method() != null && obj.method()[some_index] != null) {
...
}
Is it possible to shorten this in Kotlin with the ?.
operator?
The following non-functional pseudo-code gives an idea what I am after:
if (obj.method()?.[some_index]) {
...
}
Upvotes: 4
Views: 91
Reputation: 46180
At least in Kotlin 2.0.0 (haven't tried it in older versions), you can define a get
operator extension function for a nullable array receiver and implement it to return null if the array itself is null.
operator fun <T> Array<T>?.get(index: Int): T? = this?.get(index)
Then you can use ?.let { }
on the result of the access just like @broot's answer demonstrates, but now you can change this:
obj.method()?.get(some_index)?.let {
// ...
}
To this:
obj.method()[some_index]?.let {
// ...
}
Whether or not that is preferable is up to you. One advantage is the syntax looks cleaner, at least in my opinion. But one disadvantage is that it's no longer clear that the array returned by method()
is itself nullable.
Executable example:
operator fun <T> Array<T>?.get(index: Int): T? = this?.get(index)
fun main () {
printArray(arrayOf(Person("John"), Person("Bob"), null, Person("Amy"), null))
printArray(null)
}
fun printArray(array: Array<Person?>?) {
println("array = ${array?.contentToString()}")
// hard-coded loop for example
for (i in 0..4) {
// here's the [i]?.let { } syntax enabled by the 'get'
// extension operator function above
array[i]?.let { println(" $it") }
}
println()
}
data class Person(val name: String)
Output:
array = [Person(name=John), Person(name=Bob), null, Person(name=Amy), null]
Person(name=John)
Person(name=Bob)
Person(name=Amy)
array = null
Note when the array is null nothing is printed because the let
doesn't execute. And when the array is non-null, the let
only executes when the element in the array is also non-null.
Upvotes: 2
Reputation: 28432
Yes, we can shorten this by replacing the operator with its equivalent function call:
if (obj.method()?.get(some_index) != null)
If we need to access the value from the array if it exists and isn't null, we can additionally use let
:
obj.method()?.get(some_index)?.let {
println(it) // `it` is the value
}
Upvotes: 7