Kotlin NDArray con un constructor lambda con tipo de retorno genérico

Intento crear una class NDArray genérica muy simple en Kotlin que tome una expresión lambda como una function init.

class NDArray<T>(i: Int, j: Int, f: (Int) -> T) { val values: Array<T> = Array(i * j, f) } 

Un uso típico sería:

 fun main(args: Array<String>){ val m = NDArray(4, 4, ::zero) } fun zero(i: Int) = 0.0 

Mi problema es que el comstackdor de Kotlin se queja de la initialization de valores en el constructor

 values = Array(i * j, f) 

diciendo "No se puede usar 'T' como parámetro de tipo reificado. Use class en su lugar". Por qué ?

EDITAR:

Si, en cambio, reemploop la implementación de Kotlin Array con mi propio MyArray, comstack:

 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) { ... } 

¿No estoy seguro de por qué Kotlin trata MyArray de forma diferente a una matriz regular cuando ambas tienen el mismo constructor?

    Crear una matriz Java requiere especificar un tipo de elemento. En el caso de su class, el tipo de elemento se proporciona solo como un parámetro de tipo de la class, y los generics en Java se borran en time de ejecución. Por eso, el tipo de elemento de la matriz no se conoce, y no es posible crearlo.

    Si desea crear un contenedor personalizado alnetworkingedor de Array<T> estándar, debería tener el siguiente aspecto:

     class NDArray<reified T>(i:Int, j:Int, init: (Int) -> T) { val arr = Array<T>(i * j, init) } 

    La palabra key reified significa que su T no se borra, y puede usarse en lugares donde se necesita una class real, como llamar al constructor Array() .

    Tenga en count que esta syntax no es compatible con los constructores de class, pero sigue siendo útil para las funciones de fábrica (debe estar en inline d)

     fun <reified T> arrayFactory(i:Int, j:Int, init: (Int) -> T) = Array<T>(i * j, init) 

    Según la opinión de yole y voddan, esta es la mejor solución que encontré para el problema hasta ahora:

     class NDArray<T>(val values: Array<T> ){ companion object Factory{ inline operator fun <reified T>invoke(i: Int, j: Int, noinline init: (Int) -> T) = NDArray(Array(i * j,init)) } } 

    Esto permite el uso de reified como un constructor mediante el uso de un object complementario. La convención de llamadas de construcción se puede hacer utilizando la invocación del operador. Esto funciona ahora:

     fun main(args: Array<String>){ val m = NDArray(4,4, ::zero) } fun zero(i:Int) = 0.0 

    El único problema (a exception de la invocación de syntax intrincada ()) es que el constructor NDArray debe ser público. ¿Hay una mejor manera tal vez?

    ¡NOTA! Los siguientes problemas KT-11182 afectan este patrón de layout