在Kotlin中,有没有一种方法可以将内联函数和when表达式与扩展函数结合在一起?

时间:2019-04-10 23:57:13

标签: generics kotlin kotlin-android-extensions kotlin-extension

我想减小if-elseif-else梯形图的大小,但不能仅使用when,因为智能广播无法捕获我正在处理的情况。我想知道是否可以将letalsowhen之类的东西组合到单个内联函数中来解决这个问题。

我曾尝试将智能转换与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") } ,但这很干净,我对解决方案感到很满意。

1 个答案:

答案 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 -> ...
}