I'm trying to create a very simple generic NDArray class in Kotlin that takes a lambda expression as an init function.
class NDArray<T>(i: Int, j: Int, f: (Int) -> T) {
val values: Array<T> = Array(i * j, f)
}
A typical usage would be:
fun main(args: Array<String>){
val m = NDArray(4, 4, ::zero)
}
fun zero(i: Int) = 0.0
My problem is that the Kotlin compiler complains on the initialisation of values in the constructor
values = Array(i * j, f)
by saying "Cannot use 'T' as reified type parameter. Use class instead". Why ?
EDIT:
If I instead replace the Kotlin Array implementation with my own MyArray it compiles:
class NDArray<T>(i: Int, j: Int, f: (Int) -> T) {
val values: MyArray<T> = MyArray(i * j, f)
}
class MyArray<T>(i:Int, init: (Int) -> T) {
...
}
Not sure why Kotlin treats MyArray differently from a regular Array when both have the same constructor ?
Creating a Java array requires specifying an element type. In the case of your class, the element type is provided only as a type parameter of the class, and generics in Java are erased at runtime. Because of that, the element type of the array is not known, and it's not possible to create it.
If you would want to create a custom wrapper around standard Array<T>
, it would have to look like the following:
class NDArray<reified T>(i:Int, j:Int, init: (Int) -> T) {
val arr = Array<T>(i * j, init)
}
The reified
keyword means that your T
is not erased, and may be used in places where a real class is needed, like calling the Array()
constructor.
Note that this syntax is not supported for class constructors, but it is still useful for factory functions (must be inline
d)
fun <reified T> arrayFactory(i:Int, j:Int, init: (Int) -> T) = Array<T>(i * j, init)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With