У меня есть метод, который возвращает массив, и я проверяю, установлен ли определенный индекс. На Java я бы сделал:
if (obj.method() != null && obj.method()[some_index] != null) {
...
}
Можно ли сократить это в Котлине с помощью оператора ?.
?
Следующий нефункциональный псевдокод дает представление о том, что мне нужно:
if (obj.method()?.[some_index]) {
...
}
Да, мы можем сократить это, заменив оператор эквивалентным вызовом функции:
if (obj.method()?.get(some_index) != null)
Если нам нужно получить доступ к значению из массива, если оно существует и не равно нулю, мы можем дополнительно использовать let
:
obj.method()?.get(some_index)?.let {
println(it) // `it` is the value
}
По крайней мере, в Kotlin 2.0.0 (не пробовал в более старых версиях) вы можете определить функцию расширения оператора get
для получателя массива, допускающего значение NULL, и реализовать ее для возврата значения NULL, если сам массив имеет значение NULL.
operator fun <T> Array<T>?.get(index: Int): T? = this?.get(index)
Затем вы можете использовать ?.let { }
в результате доступа, как показано в ответе @broot, но теперь вы можете изменить это:
obj.method()?.get(some_index)?.let {
// ...
}
К этому:
obj.method()[some_index]?.let {
// ...
}
Предпочтительно это или нет, решать вам. Одним из преимуществ является то, что синтаксис выглядит чище, по крайней мере, на мой взгляд. Но одним недостатком является то, что уже неясно, является ли массив, возвращаемый method()
, сам по себе допускающим значение NULL.
Исполняемый пример:
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)
Выход:
array = [Person(name=John), Person(name=Bob), null, Person(name=Amy), null]
Person(name=John)
Person(name=Bob)
Person(name=Amy)
array = null
Обратите внимание, что когда массив равен нулю, ничего не печатается, потому что let
не выполняется. А когда массив не равен нулю, let
выполняется только тогда, когда элемент в массиве также не равен нулю.