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,因为智能广播无法捕获我正在处理的情况。我想知道我是否可以将 letalsowhen 之类的东西组合成一个内联函数来解决这个问题。

我试过使用 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 -> ...
}