Kotlin 中有没有办法将内联函数和 when 表达式与扩展函数结合起来?
Is there a way in Kotlin to combine an inline function and a when expression with an extension function?
我想减小 if-elseif-else 阶梯的大小,但不能只使用 when
,因为智能广播无法捕获我正在处理的情况。我想知道我是否可以将 let
或 also
和 when
之类的东西组合成一个内联函数来解决这个问题。
我试过使用 is
的智能转换,但这是有问题的,因为我必须在外部 when
中执行 when
才能真正获得我想要的结果。我最终做了一些类似于 post: 的响应之一,方法是让 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 中编写,如果不能,是否至少有一个替代我上面写的内容以使其更紧凑和可读?
编辑:
根据达蒙在下面的评论,我确实想到了一种更简洁的方法来解决这个问题:
when(true) {
variable?.case1 -> doSomething(variable)
variable?.case2 -> doSomethingElse(variable)
...
variable is String -> catchAll(variable)
else -> Log.e(TAG, "variable was null")
}
最好去掉 when 旁边的 (true)
,但这足够干净,我对解决方案非常满意。
您可以在 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 -> ...
}
我想减小 if-elseif-else 阶梯的大小,但不能只使用 when
,因为智能广播无法捕获我正在处理的情况。我想知道我是否可以将 let
或 also
和 when
之类的东西组合成一个内联函数来解决这个问题。
我试过使用 is
的智能转换,但这是有问题的,因为我必须在外部 when
中执行 when
才能真正获得我想要的结果。我最终做了一些类似于 post: 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 中编写,如果不能,是否至少有一个替代我上面写的内容以使其更紧凑和可读?
编辑:
根据达蒙在下面的评论,我确实想到了一种更简洁的方法来解决这个问题:
when(true) {
variable?.case1 -> doSomething(variable)
variable?.case2 -> doSomethingElse(variable)
...
variable is String -> catchAll(variable)
else -> Log.e(TAG, "variable was null")
}
最好去掉 when 旁边的 (true)
,但这足够干净,我对解决方案非常满意。
您可以在 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 -> ...
}