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

我有以下(编辑长度)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声明之前加上这个特定的调用来解决这个问题,但这很丑陋)

你有两个问题,第一个就是isArray需要返回Boolean而不是Any

第二个问题是,你使用的表达式有固定条件的形式, obj而你将它与没有固定条件的形式混合在一起,只使用布尔表达式。 这个文件不清楚的区别。

表达式的固定条件:

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

与您需要使用的表达式中的布尔表达式相比:

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

虽然找到一个数组更简单的方法是这样的:

 obj.javaClass.isArray 

所以你可以改变你的表达式,只需要:

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

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

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

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

当然,这将需要你写很多的obj == x检查。