我想减少if-elseif-else梯形图的大小,但不能只使用when
,因为smartcast没有捕捉到我正在处理的情况。我想知道我是否可以将像let
或also
和when
这样的东西组合成一个内联函数来解决这个问题。
我尝试过使用is
进行智能投射,但这是有问题的,因为我必须在外部when
中做一个when
才能真正得到我想要的结果。我最后做了一些类似于这篇文章的回复之一:Kotlin and idiomatic way to write, 'if not null, else...' based around mutable value只是让一个let
块作用于非null变量然后在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中使用扩展函数进行编写,如果没有,那么至少可以替代上面所写的内容使其更加紧凑和可读?
编辑:
根据Damon在下面的评论,我确实想到了一种稍微更清晰的方法来解决这个问题:
when(true) {
variable?.case1 -> doSomething(variable)
variable?.case2 -> doSomethingElse(variable)
...
variable is String -> catchAll(variable)
else -> Log.e(TAG, "variable was null")
}
如果可能的话,摆脱旁边的(true)
会很好,但这很干净,我对解决方案非常满意。
您可以在when语句的参数内执行强制转换。
EG
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 -> ...
}