2017-04-16 108 views
2

我试图通过定义运算符一次来减少一些向量类型的重复,但我不确定这是否可能。这似乎是最有前途的方法: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()) 
    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)) 

这给了我“派生类型参数不能被称为功能”,我试图建立我的派生返回值。

在Kotlin中可以做到这一点吗?

回答

3

你不能直接做到这一点,因为在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()) 

    // ... 
} 

然后你在每一个派生类中重写这个功能:

class Vec2(x: Float, y: Float) : VecN<Vec2>(floatArrayOf(x, y)) { 
    override protected fun createNew(buffer: FloatArray) = Vec2(buffer[0], buffer[1]) 
} 

(demo of this code)

+0

谢谢:这是做的伎俩。 Float :: minus也很好。 (缺少一个构造函数接受一个数组是一个复制/粘贴的监督。) –