简体   繁体   English

为什么函数的结果不能在Kotlin中的when语句中用作子句?

[英]Why won't the result of a function work as a clause in a when statement in Kotlin?

I have the following (edited for length) Kotlin functions: 我有以下(按长度编辑)Kotlin函数:

fun getType(obj: Any?): String {
    if (obj != null)
        println("$obj -> isArray:${isArray(obj)}")

    return when (obj) {
        null -> "null"
        [...]
        isArray(obj) -> "Array"
        else -> "Other object"
    }
}

private fun isArray(obj: Any): Any = 
        obj is Array<*> ||
        [...]
        obj is IntArray

When I assertEquals("Array", getType(intArrayOf(1,2,3,4))) I get the following output: 当我assertEquals("Array", getType(intArrayOf(1,2,3,4)))我得到以下输出:

[I@1e25b76 -> isArray:true

org.junit.ComparisonFailure: 
Expected :Array
Actual   :Other object

So the isArray call is returning true , but it's not being recognised in the when clause. 因此, isArray调用返回的是true ,但是在when子句中未被识别。 Why wouldn't it return "Array" here? 为什么它不返回"Array"

(I can work around this by putting this specific call before the when statement, but that's ugly) (我可以通过将此特定调用放在when语句之前来解决此问题,但这很丑陋)

You have two issues, first is that isArray needs to return Boolean and not Any . 您有两个问题,首先是isArray需要返回Boolean而不是Any

The second problem is that you are using the form of when expression that has a fixed condition, obj and you are mixing that with the form of when that has no fixed condition and uses only boolean expressions. 第二个问题是,您正在使用条件条件固定的when表达式 obj的形式,并且将它与条件条件不固定且仅使用布尔表达式的when形式混合。 The documentation isn't clear on the difference. 关于差异的文档尚不清楚。

Fixed condition when expression: 表达式when固定条件:

when(obj) {
    null -> "null"
    is Array<*>, is IntArray, is DoubleArray -> "Array"
    else -> "Other object"
}

versus what you need to use, boolean expressions in a when expression: 与您需要使用的内容相比, when表达式中的布尔表达式:

when {                            // <--- no (obj) here
    obj == null -> "null"
    isArray(obj) -> "Array"
    else -> "Other object"
}

Although a much simpler way to find an array is this: 尽管找到数组的简单得多的方法是:

obj.javaClass.isArray

So you can change your when expression to simply be: 因此,您可以将when表达式更改为:

when {
    obj == null -> "null"
    obj.javaClass.isArray -> "Array"
    else -> "Other object"
}
return when (obj) {
    null -> "null"
    [...]
    isArray(obj) -> "Array"
    else -> "Other object"
}

This seems to match the result of isArray(obj) (a Boolean ) to the obj itself. 这似乎使isArray(obj) (一个Boolean )的结果与obj本身匹配。 Therefore, it's making the comparison obj == true , which is false. 因此,它使比较obj == true ,这是错误的。

If you want a when expression that uses boolean statements, you can do: 如果需要使用布尔语句的when表达式,则可以执行以下操作:

return when {
    obj == null -> "null"
    [...]
    isArray(obj) -> "Array"
    else -> "Other object"
}

Of course, this will require you to write a lot of obj == x checks. 当然,这将需要您编写很多obj == x支票。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么当 println() function 在 Kotlin 中工作时,此返回语句不起作用? - Why doesn't this return statement work while the println() function works in Kotlin? 当我在Kotlin中使用原始parseList函数时,为什么我得不到正确的结果? - Why don't I get correct result when I use original parseList function in Kotlin? 为什么我的 java api 不能与 gradle 'from components.java' 但与 'from components.kotlin' 一起工作 - Why my java api won't work with gradle 'from components.java' but with 'from components.kotlin' 为什么JobScheduler在Kotlin不起作用? - Why doesn't JobScheduler work in Kotlin? Kotlin协程不会立即编译(挂起功能?) - Kotlin coroutine won't compile without delay (suspend function?) 为什么 CustomTabsClient.bindCustomTabsService 不起作用? - Why won't CustomTabsClient.bindCustomTabsService work? 为什么 Kotlin 智能演员不起作用,即使两者都是`val` - Why DOESN’T Kotlin smart cast work, even when both are `val`s 为什么不能将“kotlin.Result”用作返回类型? - Why can't 'kotlin.Result' be used as a return type? 为什么Kotlin打印声明不需要范围说明? - Why doesn't the Kotlin print statement require scope clarification? 无法在Kotlin中的tailrec函数中返回阶乘结果 - Can't return factorial result in tailrec function in Kotlin
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM