我想减小if-elseif-else梯形图的大小,但不能仅使用when
,因为智能广播无法捕获我正在处理的情况。我想知道是否可以将let
或also
和when
之类的东西组合到单个内联函数中来解决这个问题。
我曾尝试将智能转换与is
一起使用,但这是有问题的,因为我必须在外部when
内进行一个when
才能真正获得所需的结果。我最终做了与这篇帖子之一类似的操作:Kotlin and idiomatic way to write, 'if not null, else...' based around mutable value,只是对非null变量执行一个let
块,然后在该{{ 1}}。
我目前要处理的情况:
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")
}
是否可以使用Kotlin的扩展功能编写代码,如果没有,至少可以替代我上面写的内容,以使其更紧凑,更易读?
编辑:
基于下面达蒙的评论,我确实想到了一种更简洁的方法来解决此问题:
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")
旁边的when(true) {
variable?.case1 -> doSomething(variable)
variable?.case2 -> doSomethingElse(variable)
...
variable is String -> catchAll(variable)
else -> Log.e(TAG, "variable was null")
}
,但这很干净,我对解决方案感到很满意。
答案 0 :(得分:1)
您可以在when语句的参数内部执行强制转换。
例如
when (variable as? Type) {
case1 -> ...
case2 -> ...
null -> ...
else -> ...
}
另一个基于评论的示例:
enum class UrlType { TYPE_1, TYPE_2, TYPE_3, NULL }
fun String?.urlType(): UrlType {
return when {
this?.contains("...") == true -> UrlType.TYPE_1
this?.startsWith("...") == true -> UrlType.TYPE_2
this != null -> UrlType.TYPE_3
else -> UrlType.NULL
}
}
when (variable.urlType()) {
UrlType.TYPE_1 -> doSomething()
UrlType.TYPE_2 -> doSomethingElse()
UrlType.TYPE_3 -> ...
UrlType.NULL -> ...
}