当前位置: 首页 > 知识库问答 >
问题:

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

丌官招
2023-03-14

我试图在静态编程语言中创建一个非常简单的泛型NDArray类,它将lambda表达式作为初始化函数。

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’作为具体化类型参数。改用类”。为什么?

编辑:

如果我用我自己的MyArray替换静态编程语言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与常规数组不同,当两者具有相同的构造函数时?

共有2个答案

洪景铄
2023-03-14

根据yole和voddan的意见,这是迄今为止我发现的解决问题的最佳方案:

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

这允许通过使用伴随对象将具体化用作构造函数。构造调用约定可以使用运算符调用来完成。这现在有效:

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

fun zero(i:Int) =  0.0 

唯一的问题(复杂语法invoke()除外)是NDArray构造函数需要是公共的。也许有更好的方法吗?

注意!以下问题KT-11182影响此设计模式

公羊渝
2023-03-14

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

如果要围绕标准数组创建自定义包装器

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

“reified”(具体化)关键字意味着不会删除您的T,并且可以在需要实际类的地方使用,例如调用数组()构造函数。

注意,类构造函数不支持此语法,但它对工厂函数仍然有用(必须是内联的)

fun <reified T> arrayFactory(i:Int, j:Int, init: (Int) -> T) = Array<T>(i * j, init)
 类似资料:
  • (沙盒) 获取此错误: 类型“number”不可分配给类型“T”“number”可分配给“T”类型的约束,但“T”可以用约束{}的不同子类型实例化。(2322)输入。ts(1,26):预期类型来自此签名的返回类型。 我希望typescript能够自动推断T为数字,然后直接使用它。为什么它在抱怨?写这样的东西的正确方法是什么?谢谢

  • 问题内容: 对于一个抽象类,我想定义一个为子类返回“ this”的方法: 我希望能够执行以下操作: 可以说香蕉面包会抛出一个IllegalArgumentException消息“不是蛋糕!”。 问题答案: 编辑 要求子类以某种方式表现是没有问题的,这超出了静态类型可以检查的范围。我们一直在这样做-一页又一页的普通英语指定您如何编写子类。 提出的另一种具有协变返回类型的解决方案必须做同样的事情-用简

  • 我正在尝试返回一个对象,它应该是IClass的一个实现,具有一个通用类型,是IType的一个实现。 我要返回的实际类扩展了Class (abstract ),其泛型类型为ActualType: 抽象类对象实现了IClass接口,可以有任何扩展IType的类型 ActualType只是实现了IType接口 我在编译时得到一个“类型不匹配:无法从ActualClass转换为IClass”错误。我不明白

  • 问题内容: 所以我有一张地图: 我会像这样添加元素: 我有如下通用方法: 现在,这段代码可以很好地工作,并且没有编译器问题: 但是,当我尝试这样做时: 编译器向我显示以下警告:类型安全:通用方法verifyType(String,Class)的未经检查的调用verifyType(String,Class) 这让我感到困惑…请帮助… 问题答案: 更改: 至 通过仅将类型声明为“ Class”,就失去

  • 我有一个问题,从抽象类中重写泛型方法。 这是我的抽象类: 当我创建类(B)来实现类(a)时,如下所示: 显示了(getData)方法中的以下编译错误: ”“B。getData“(“字符串函数(字符串)”不是“a”的有效重写。getData'('字符串函数(类型)‘)。dart(无效覆盖) 以及返回语句中的此错误: 类型为“String”的值不能从方法'getData'返回,因为它的返回类型为'St

  • 我正在尝试用来自spring WebFlux的WebClient制作一个客户端库。 服务器返回如下JSON所示的响应: 结果字段包含元素数组,这些元素可以根据使用的API而不同。 有关该API的更多信息,请参阅ServiceNow产品中的表API。 正如您在文档中所看到的,API路径如下所示:GET/now/table/{tableName},其中tableName可以是不同的值,tipology