Kotlin:在基类中构造派生泛型类型的值

Kotlin:在基类中构造派生泛型类型的值,kotlin,Kotlin,我试图通过定义一次操作符来减少某些向量类型之间的重复,但我不确定这是否可行。这似乎是最有希望的方法: open class VecN<Derived: VecN<Derived>>(val buffer: FloatArray) { operator fun minus(other: Derived) = Derived(buffer.zip(other.buffer, { a, b -> a - b }).toFloatArray()) opera

我试图通过定义一次操作符来减少某些向量类型之间的重复,但我不确定这是否可行。这似乎是最有希望的方法:

open class VecN<Derived: VecN<Derived>>(val buffer: FloatArray) {
    operator fun minus(other: Derived) = Derived(buffer.zip(other.buffer, { a, b -> a - b }).toFloatArray())
    operator fun plus(other: Derived) = Derived(buffer.zip(other.buffer, { a, b -> a + b }).toFloatArray())
    ... many more operators...
}

class Vec2(x: Float, y: Float) : VecN<Vec2>(floatArrayOf(x, y))
class Vec3(x: Float, y: Float, z: Float) : VecN<Vec3>(floatArrayOf(x, y, z))
class Vec4(x: Float, y: Float, z: Float, w: Float) : VecN<Vec4>(floatArrayOf(x, y, z, w))
开放类VecN(val缓冲区:FloatArray){
运算符fun减号(其他:派生)=派生(buffer.zip(其他.buffer,{a,b->a-b}).toFloatArray())
运算符fun plus(other:Derived)=派生(buffer.zip(other.buffer,{a,b->a+b}).toFloatArray())
…更多的操作员。。。
}
类Vec2(x:Float,y:Float):VecN(floatArrayOf(x,y))
类Vec3(x:Float,y:Float,z:Float):VecN(floatArrayOf(x,y,z))
类Vec4(x:Float,y:Float,z:Float,w:Float):VecN(floatArrayOf(x,y,z,w))
这给了我“派生的类型参数不能作为函数调用”,在这里我试图构造派生的返回值


在Kotlin中有可能实现这一点吗?

您不能直接这样做,因为在Kotlin中,您只能调用具体类型的构造函数,而无法调用类型参数的构造函数。此外,Kotlin不允许将数组传递到需要固定数量的独立值的函数/构造函数中

但是,您可以尝试在不使用太多样板文件的情况下使用抽象函数来实现这一点,如下所示:

abstract class VecN<Derived: VecN<Derived>>(val buffer: FloatArray) {
    protected abstract fun createNew(buffer: FloatArray): Derived 

    operator fun minus(other: Derived) = 
        createNew(buffer.zip(other.buffer, Float::minus).toFloatArray())

    // ...
}
抽象类VecN(val缓冲区:FloatArray){
受保护的抽象元素createNew(缓冲区:FloatArray):派生
运算符fun减号(其他:派生)=
createNew(buffer.zip(other.buffer,Float::minus).toFloatArray())
// ...
}
然后必须在每个派生类中重写此函数:

class Vec2(x: Float, y: Float) : VecN<Vec2>(floatArrayOf(x, y)) {
    override protected fun createNew(buffer: FloatArray) = Vec2(buffer[0], buffer[1])
}
类Vec2(x:Float,y:Float):VecN(floatArrayOf(x,y)){
重写受保护的新(缓冲区:FloatArray)=Vec2(缓冲区[0],缓冲区[1])
}

谢谢:这就成功了。
Float::减号也很不错。(缺少接受数组的构造函数是复制/粘贴疏忽。)