Kotlin中是否可以将内联函数和when表达式与扩展函数结合在一起?

Rya*_*hea 5 generics kotlin kotlin-extension kotlin-android-extensions

我想减小if-elseif-else梯形图的大小,但不能仅仅when因为智能广播无法捕获我正在处理的情况而使用。我想知道是否可以将诸如a let或an also和a之类的内容组合when到单个内联函数中以解决此问题。

我已经尝试过将智能投射与一起使用,is但这是有问题的,因为我必须when在外部when进行a 运算才能真正获得想要的结果。我最终做了与这篇文章中的一个响应类似的事情:Kotlin和惯用的方式,基于可变的值,通过使一个let块作用于非null变量,然后执行,来编写“如果不为null,否则...”when内部的块let

案例我目前正在处理:

variable?.let { safeVariable ->
    when {
        case1 -> doSomething(safeVariable)
        case2 -> doSomethingElse(safeVariable)
         ...
        else -> catchAll(safeVariable)
    }
    return@let
}
Log.e(TAG, "variable was null")
Run Code Online (Sandbox Code Playgroud)

我考虑过的案例:

when(variable) {
    is Type -> when {
                   case1 -> doSomething(variable)
                   case2 -> doSomethingElse(variable)
                   ...
                   else -> catchAll(variable)
               }
   else -> Log.e(TAG, "variable was null")
}
Run Code Online (Sandbox Code Playgroud)
if (variable is Type) {
    when {
        case1 -> doSomething(variable)
        case2 -> doSomethingElse(variable)
         ...
        else -> catchAll(variable)
    }
} else {
    Log.e(TAG, "variable was null")
}
Run Code Online (Sandbox Code Playgroud)

我想要写的内容如下所示:

variable?.alsoWhen { safeVariable ->
    case1 -> doSomething(safeVariable)
    case2 -> doSomethingElse(safeVariable)
     ...
    else -> catchAll(safeVariable)
} ?: Log.e(TAG, "variable was null")
Run Code Online (Sandbox Code Playgroud)

是否可以使用Kotlin的扩展功能编写代码,如果没有,至少没有我上面编写的替代方法可以使它更紧凑和易读?

编辑:

基于Damon在下面的评论,我确实想到了一种更简洁的方法来解决此问题:

when(true) { 
    variable?.case1 -> doSomething(variable) 
    variable?.case2 -> doSomethingElse(variable) 
     ... 
    variable is String -> catchAll(variable)
    else -> Log.e(TAG, "variable was null") 
} 
Run Code Online (Sandbox Code Playgroud)

如果可能的话,最好除掉(true)next,但这很干净,我对解决方案非常满意。

Dam*_*ker 1

您可以在when 语句的参数内执行强制转换。

例如

when (variable as? Type) {
    case1 -> ...
    case2 -> ...
    null -> ...
    else -> ...
}
Run Code Online (Sandbox Code Playgroud)

基于评论的另一个例子:

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 -> ...
}
Run Code Online (Sandbox Code Playgroud)