2017-04-16 81 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也很好。 (缺少一個構造函數接受一個數組是一個複製/粘貼的監督。) –