在Kotlin中有没有办法将内联函数和when表达式与扩展函数结合起来?

问题描述 投票:4回答:1

我想减少if-elseif-else梯形图的大小,但不能只使用when,因为smartcast没有捕捉到我正在处理的情况。我想知道我是否可以将像letalsowhen这样的东西组合成一个内联函数来解决这个问题。

我尝试过使用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)会很好,但这很干净,我对解决方案非常满意。

generics kotlin kotlin-android-extensions kotlin-extension
1个回答
1
投票

您可以在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 -> ...
}
© www.soinside.com 2019 - 2024. All rights reserved.