Я хотел бы уменьшить размер лестницы if-elseif-else, но не могу использовать только when
, потому что smartcast не улавливает случаи, с которыми я имею дело. Мне интересно, могу ли я объединить что-то вроде let
или also
и when
в одну встроенную функцию для решения этой проблемы.
Я пытался использовать умное приведение с is
, но это проблематично, потому что мне пришлось бы сделать when
внутри внешнего when
, чтобы на самом деле получить желаемый результат. Я закончил тем, что делал что-то похожее на один из ответов из этого поста: Котлин и идиоматический способ написания 'если не ноль, иначе ...', основанный на изменяемом значении , просто имея блок let
воздействуя на ненулевую переменную, затем выполняя блок when
внутри этого let
.
Случай, с которым я сейчас работаю:
variable?.let { safeVariable ->
when {
case1 -> doSomething(safeVariable)
case2 -> doSomethingElse(safeVariable)
...
else -> catchAll(safeVariable)
}
return@let
}
Log.e(TAG, "variable was null")
Случаи, которые я рассмотрел:
when(variable) {
is Type -> when {
case1 -> doSomething(variable)
case2 -> doSomethingElse(variable)
...
else -> catchAll(variable)
}
else -> Log.e(TAG, "variable was null")
}
if (variable is Type) {
when {
case1 -> doSomething(variable)
case2 -> doSomethingElse(variable)
...
else -> catchAll(variable)
}
} else {
Log.e(TAG, "variable was null")
}
То, что я хотел бы написать, выглядело бы так:
variable?.alsoWhen { safeVariable ->
case1 -> doSomething(safeVariable)
case2 -> doSomethingElse(safeVariable)
...
else -> catchAll(safeVariable)
} ?: Log.e(TAG, "variable was null")
Можно ли написать на Kotlin с помощью функции расширения, и если нет, то есть хотя бы альтернатива тому, что я написал выше, чтобы сделать его более компактным и читаемым?
EDIT:
Основываясь на комментариях Дэймона ниже, я подумал о несколько более чистом способе подойти к этому:
when(true) {
variable?.case1 -> doSomething(variable)
variable?.case2 -> doSomethingElse(variable)
...
variable is String -> catchAll(variable)
else -> Log.e(TAG, "variable was null")
}
Было бы неплохо, если возможно, избавиться от (true)
рядом с буквой, но это достаточно чисто, так что я довольно доволен решением.