Почему результат функции не работает как предложение в заявлении 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 вызов isArray возвращает true , но он не распознается в предложении when . Почему бы ему не вернуть "Array" здесь?

(Я могу обойти это, поставив этот конкретный вызов перед оператором when , но это уродливо)

У вас есть две проблемы: во-первых, isArray должен возвращать Boolean а не Any .

Вторая проблема заключается в том, что вы используете форму выражения expression с фиксированным условием obj и вы смешиваете это с формой, when у него нет фиксированного условия и используются только булевы выражения. В этой документации не ясно.

Исправлено условие, when выражение:

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

в сравнении с тем, что вам нужно использовать, логические выражения в выражении if:

 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) (a Boolean ) на сам obj . Следовательно, он делает сравнение obj == true , что является ложным.

Если вы хотите, чтобы выражение when , использующее логические операторы, вы можете сделать:

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

Конечно, это потребует от вас написать много проверок obj == x .