Reputation: 2113
Take a look at this code:
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())
}
}
I'm getting this error at the last line:
t.kt:6:23: error: type mismatch: inferred type is Array<(out) Any!>! but Array<T> was expected
CycleArray<T>(ret.toArray())
As you can see I've specified the element type of destination ArrayList to be T
. Why am I getting this error?
Upvotes: 0
Views: 953
Reputation: 2015
The Java toArray method you are calling returns type Object[]
which in Kotlin is Any[]
. The problem is that the CycleArray
constructor call is expecting the type T
.
The List
interface provides another toArray which accepts an initialised array of the expected type in order to determine the correct return type. This however will not work with a generic type as the type needs to be known at compile time. There is a particular way around this kind of problem in koltin which is to use a reified type:
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>()))
}
This is not entirely suited to your situation however, because the class is generic, not the method. The downside of doing this is that you will have to specify the type when calling the method:
val obj = CycleArray<Int>(arrayOf(1, 2, 3))
val result = obj.cycle<Int>()
This is most certainly not ideal but will work. Otherwise you should rethink the design. Is it absolutely necessary that CycleArray
accepts an Array as its argument? If not, opt for a List to begin with.
Upvotes: 2
Reputation: 1637
Since a kotlin Array<T>
is compiled to Java T[]
, you can only do this if you know the type T
at compile time - but you don't, that's why you get the error.
What you could do instead is use 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)
}
}
When you really need an Array
as parameter type, you could look into reified type parameters. Not sure if you can apply this to your use-case though, since I don't know the rest of your code.
However, there seem to be some logical issues in your code, for example you never use the idxs
in your function...
Upvotes: 0