具有泛型返回类型的 lambda 构造函数的 Kotlin NDArray

2023-12-19

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

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

典型的用法是:

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

fun zero(i: Int) =  0.0

我的问题是 Kotlin 编译器抱怨构造函数中值的初始化

values = Array(i * j, f)

说“不能使用‘T’作为具体化类型参数。请使用类”。为什么 ?

EDIT:

如果我用我自己的 MyArray 替换 Kotlin Array 实现,它会编译:

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

不知道为什么当 MyArray 具有相同的构造函数时,Kotlin 对待 MyArray 的方式与常规 Array 不同?


创建 Java 数组需要指定元素类型。对于您的类,元素类型仅作为类的类型参数提供,并且 Java 中的泛型会在运行时被删除。因此,数组的元素类型未知,并且无法创建它。

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

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

The reified关键字意味着您的T不会被删除,并且可以在需要真正的类的地方使用,例如调用Array()构造函数。

请注意,这不支持语法对于类构造函数,但它对于工厂函数仍然有用(必须是inlined)

fun <reified T> arrayFactory(i:Int, j:Int, init: (Int) -> T) = Array<T>(i * j, init)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有泛型返回类型的 lambda 构造函数的 Kotlin NDArray 的相关文章

随机推荐