Kotlin NDArray带有带泛型返回类型的lambda构造函数 [英] Kotlin NDArray with a lambda constructor with generic return type

查看:258
本文介绍了Kotlin NDArray带有带泛型返回类型的lambda构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Kotlin中创建一个非常简单的通用NDArray类,它将一个lambda表达式作为init函数。

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

典型的用法是: / p>

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

fun zero(i:Int)= 0.0



<我的问题是Kotlin编译器抱怨在构造函数中初始化值
$ b $ pre $ values = Array(i * j, f)

通过说不能使用'T'作为实体类型参数。为什么?



编辑:

如果我用Kotlin Array实现替换我自己编写的MyArray:

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

class MyArray< T>(i:Int,init:(Int) - > T){
...
}

不知道为什么Kotlin将MyArray视为与常规数组不同构造函数?

解决方案

创建一个Java数组需要指定一个元素类型。在您的类中,元素类型仅作为类的类型参数提供,Java中的泛型会在运行时擦除。因此,数组的元素类型是未知的,并且不可能创建它。



如果您希望围绕标准<$创建自定义包装c $ c> Array< T> ,它必须如下所示:

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

通过关键字表示您的 T 不会被擦除,并可能用于需要真实类的地方,如调用 Array()构造函数。注意这个语法不支持类构造函数,但它对工厂函数仍然有用(必须是 inline d)

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


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 inlined)

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

这篇关于Kotlin NDArray带有带泛型返回类型的lambda构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆