Kotlin NDArray with a lambda constructor with generic return type
arrays, generics, kotlin, type-erasure
Solution
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)
Problem
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 ?