Создание ArrayList из массива в kotlin - PullRequest
0 голосов
/ 16 декабря 2018

Посмотрите на этот код:

class CycleArray<T>(val elems: Array<T>) {

    fun cycle(vararg idxs : Int) : CycleArray<T> {
        val ret = elems.sliceArray(1 until elems.size).toCollection(ArrayList<T>())
        ret.add(0, elems[elems.size - 1])
        return CycleArray<T>(ret.toArray())
    }
}

Я получаю эту ошибку в последней строке:

t.kt:6:23: error: type mismatch: inferred type is Array<(out) Any!>! but Array<T> was expected
        CycleArray<T>(ret.toArray())

Как вы можете видеть, я указал тип элементаArrayList назначения будет T.Почему я получаю эту ошибку?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Метод Java toArray , который вы вызываете, возвращает тип Object[], который в Kotlin равен Any[].Проблема в том, что вызов конструктора CycleArray ожидает тип T.

Интерфейс List предоставляет еще один toArray , который принимает инициализированный массив ожидаемого типа для определения правильного возвращаемого типа.Это, однако, не будет работать с универсальным типом, так как тип должен быть известен во время компиляции.Существует особый способ обойти проблему такого рода в koltin, которая заключается в использовании типа reified :

inline fun <reified T> cycle(vararg idxs : Int) : CycleArray<T> {
    val ret = elems.sliceArray(1 until elems.size).toCollection(ArrayList())
    ret.add(0, elems[elems.size - 1])

    return CycleArray<T>(ret.toArray(arrayOf<T>()))
}

Однако это не совсем подходит для вашей ситуации, поскольку класс является универсальнымне метод.Недостатком этого является то, что вам придется указывать тип при вызове метода:

val obj = CycleArray<Int>(arrayOf(1, 2, 3))
val result = obj.cycle<Int>()

Это, безусловно, не идеально, но будет работать.В противном случае вы должны переосмыслить дизайн.Абсолютно необходимо, чтобы CycleArray принял Array в качестве аргумента?Если нет, выберите Список для начала.

0 голосов
/ 16 декабря 2018

Поскольку kotlin Array<T> скомпилирован в Java T[], вы можете сделать это, только если вы знаете тип T во время компиляции, но не знаете, поэтому вы получаете сообщение об ошибке.

Вместо этого вы можете использовать ArrayLists:

class CycleArray<T>(val elems: ArrayList<T>) {

    fun cycle(vararg idxs : Int) : CycleArray<T> {
        val ret = elems.slice(1 until elems.size).toCollection(ArrayList())
        ret.add(0, elems[elems.size - 1])
        return CycleArray(ret)
    }
}

Когда вам действительно нужен Array в качестве типа параметра, вы можете посмотреть параметры уточненного типа .Не уверен, что вы можете применить это к своему варианту использования, поскольку я не знаю остальную часть вашего кода.

Однако в вашем коде, похоже, есть некоторые логические проблемы, например, вы никогда не используетеidxs в вашей функции ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...