Котлин когда выражение автопередача
Я хотел бы, чтобы следующий код kotlin работал:
val result: Try<Option<String>> = Success(Some("test"))
val test = when {
result is Success && result.value is Some -> result.value.t // not working
result is Success && result.value is None -> "Empty result"
result is Failure -> "Call failed!"
else -> "no match!"
}
Я использую библиотеку стрелок для монады Try and Option.
К сожалению, я могу получить доступ только к значению первого условия "есть успех", а не ко второму условию "есть некоторые". Таким образом, я могу сделать только "result.value", тогда я получу опцию String.
Я что-то пропустил? Это сэкономит мне много внутренних вызовов ".map" и ".fold".
Обновить:
Мне нужно сначала разыграть это, что некрасиво:
result is Success && result.value is Some -> (result.value as Some<String>).t
2 ответа
Я попробовал ваш пример в IntelliJ с Kotlin 1.3.21. Это показывает причину проблемы:
Вам нужно извлечь result.value
в качестве переменной, чтобы заставить его работать. Я нашел следующий фрагмент, чтобы решить это
val result: Try<Option<String>> = Success(Some("test"))
val test = when (result) {
is Success -> when(val value = result.value) {
is Some -> value.t
is None -> "None"
}
is Failure -> "Call failed!"
else -> "no match!"
}
Я использую Kotlin 1.3.x when
с синтаксисом объявления.
Вы также можете использовать Arrow API для получения аналогичного результата:
val test = result.fold(
ifSuccess = { it.getOrElse { "None" }},
ifFailure = { "Call failed!" }
)
Здесь вам не нужно иметь else
пункт в when
,
Вы можете упростить сопоставление с шаблоном следующим образом:
val test = result
.map { it.getOrElse { "Empty result"} }
.getOrElse { "Call failed!" }
Что является более исчерпывающим и не требует else
альтернатива
В качестве альтернативы, если вас не волнует выбрасываемое исключение, вы можете использовать toOption
на Try
:
val test = result
.toOption()
.getOrElse { "No value!!" }
Однако это приводит к некоторой очевидной потере информации.
Я бы лично Try
экземпляр для потребителя результата рушится Option
с .map
так что конечный результат имеет тип Try<String>
и пусть потребитель обработает ошибку.
Тем не менее, это зависит от реального контекста проблемы.