Можно ли сделать следующий код для компиляции в Kotlin?
val variable: String? = "string"
val (a, b) = variable?.run {
1 to 2
}
Можно ли сделать следующий код для компиляции в Kotlin?
val variable: String? = "string"
val (a, b) = variable?.run {
1 to 2
}
Компилятор не разрешает деструктурирование, поскольку выражение в правой части имеет тип Pair<Int, Int>?
, допускающий значение NULL, и неясно, какие значения должны получить a
и b
, если variable
равно NULL.
Чтобы решить эту проблему, вам нужно получить ненулевое выражение после =
.
Существует множество различных способов обработки значений, допускающих значение NULL, и получения ненулевого значения из значения, допускающего значение NULL, см.: Как в Kotlin идиоматично работать с нулевыми значениями, ссылаясь на них или преобразовывая их
Например, если вы хотите предоставить резервные значения для a
и b
, используйте оператор ?:
следующим образом:
val (a, b) = variable?.run {
1 to 2
} ?: (0 to 0)
Альтернативой, например, было бы сначала проверить variable
на null:
val (a, b) = checkNotNull(variable) { "variable should never be null" }.run {
1 to 2
}
Null не имеет деструктурирующих объявлений. Если вы хотите, чтобы значение null деструктурировалось как пара нулей, вы можете добавить следующие расширения:
operator fun <T> Pair<T, *>?.component1() = this?.component1()
operator fun <T> Pair<*, T>?.component2() = this?.component2()
В противном случае, как показывает другой ответ, вам необходимо указать значение по умолчанию с помощью оператора Элвиса.
Он не автоматический, потому что не знает, чего вы хотите. В зависимости от того, что вы с ним делаете, 0 to 0
может быть наиболее подходящим, или, может быть, -1 to -1
или 0 to null
или null to null
.
null to null
. 05.03.2020 null to null
, чтобы оно работало для любых типов. 05.03.2020 Вопрос в том, что вы хотите сделать, если ваша переменная равна нулю? Если вы хотите создать исключение, используйте require
или check
, как предложил @hotkey.
Однако у меня есть случай, когда я просто хочу вернуться, если значение равно null. Поэтому я написал себе небольшую вспомогательную функцию, которая позволяет это сделать:
private inline fun <T> T?.exitIfNull(exitBlock: () -> Nothing): T {
if (this == null)
exitBlock()
else
return this
}
Вы можете вызвать эту функцию следующим образом:
val (a, b) = variable?.run {
1 to 2
}.exitIfNull {
return
}
Приятное небольшое использование ключевого слова Nothing
в Kotlin, которое я лично нахожу весьма захватывающим.
a
иb
должны быть равны нулю, еслиvariable
равно нулю, или я что-то упускаю?variable
может быть нулевым, и в этом случае резервные значения должны быть нулевыми. 04.03.2020?: (null to null)
в конце, и это сработало, но я считаю, что это можно сделать автоматически. 04.03.2020null as Int? to null as Int?
, если вы хотите, чтобыa
иb
былиInt?
, а неAny?
. 04.03.2020