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

时间:2016-09-20 11:22:29

标签: kotlin

我有以下(编辑长度)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

当我assertEquals("Array", getType(intArrayOf(1,2,3,4)))时,我得到以下输出:

[I@1e25b76 -> isArray:true

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

因此isArray调用正在返回true,但在when子句中无法识别。为什么不在这里返回"Array"

(我可以通过在when语句之前进行此特定调用来解决此问题,但这很难看)

2 个答案:

答案 0 :(得分:4)

您有两个问题,首先是isArray需要返回Boolean而不是Any

第二个问题是,您使用的when expression形式具有固定条件obj,并且您将其与when形式混合,没有固定条件,仅使用布尔表达式。文件不清楚差异。

固定条件when表达式:

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

与您需要使用的内容,when表达式中的布尔表达式:

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

虽然找到数组的一种更简单的方法是:

obj.javaClass.isArray

因此,您可以将when表达式更改为:

when {
    obj == null -> "null"
    obj.javaClass.isArray -> "Array"
    else -> "Other object"
}

答案 1 :(得分:2)

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

这似乎与isArray(obj)Boolean)与obj本身的结果相匹配。因此,它正在进行比较obj == true,这是错误的。

如果你想要一个使用布尔语句的when表达式,你可以这样做:

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

当然,这需要您编写大量obj == x项支票。