arrayOf
вернуть Array<T>
. Если вы хотите IntArray, а не Array<Int>
, вы ищете intArrayOf
.
Основная проблема заключается в том, что IntArray
- это int[]
, где Array<T>
преобразуется в целое число []. И здесь вы, вероятно, можете сказать, почему он не работает: int[]
не является экземпляром Integer[]
, а наоборот. Или, по крайней мере, основное преобразование не удается.
Наблюдаемые типы Array и IntArray также различаются, но это различие во время выполнения, которое подтверждает, почему он ломается.
Если вы намереваетесь также принимать массивы, такие как IntArray и FloatArray (примитивные массивы), проблема в том, что у них нет общего суперкласса. Нет коллекции, нет итерируемой, только Any
. Это означает, что вы не можете выполнить ветвь с несколькими типами для них.
Как уже упоминалось в другом ответе, вы можете использовать рекурсивный подход. И, как я уже говорил, оператор when исключает IntArray, FloatArray и подобные из операторов multi-catch когда. Для этого нужны отдельные ветки, если вы планируете их обрабатывать. Кроме того, массив также не является итерируемым, что означает, что вам также нужна отдельная ветвь для него. К счастью, вам не нужны ветки для каждого из универсальных типов, хотя в процессе вы обнаружите, что набрали Any?
.
// This function is just here to show what I've based this off (and make any misunderstandings visible early)
fun processMap(map: Map <String, Any>) {
for ((key, value) in map) {
/*return value(s) = */
processValue(value);
}
}
fun processValue(value: Any?) {
when (value) {
// ... other types. I'm going to assume doWork acts differently based on types, but
// if it is the same function and there are no type differences, you can
// merge them into a single branch with:
//
// is String, is Int, is Float, is Double -> doWork(value)
// ...
is String -> doWork(value)
is Int -> doWork(value)
is Float -> doWork(value)
is Double -> doWork(value)
// ...
// Process lists, collections, and other Iterables.
is Iterable<*> -> value.forEach { processValue(it) }
// Process Arrays
is Array<*> -> value.forEach { processValue(it) }
// Process primitive arrays
is IntArray -> value.forEach { processValue(it) }
is FloatArray -> value.forEach { processValue(it) }
// And so on
}
}
Если вы планируете обрабатывать карты, вы можете использовать is Map<*, *>
и обрабатывать свои элементы любым удобным для вас способом.
Разделение Array
, IntArray
и FloatArray
должно заставить работать умное приведение. Если вы объединяете их в одну ветку, она разрывается, потому что не может определить тип. Это означает, что вы возвращаетесь к Any
, который автоматически не имеет метода iterator()
, который предотвращает как value.forEach
, так и for(item in value)
. Отсутствие общего интерфейса для IntArray
, FloatArray
и тому подобного не облегчает эту задачу.
Оба они производят один и тот же экземпляр, так что Array<Int>.forEach
и IntArray.forEach
оба вызовут ветку is Int
вашего оператора when.
Связанные ресурсы