【问题标题】:Kotlin: Construct value of derived generic type in base classKotlin:在基类中构造派生泛型类型的值
【发布时间】:2017-04-17 07:57:02
【问题描述】:

我试图通过定义一次运算符来减少某些向量类型的重复,但我不确定这是否可能。这似乎是最有前途的方法:

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

这给了我“类型参数 Derived 不能被称为函数”,我尝试在其中构造我的 Derived 返回值。

在 Kotlin 中可以实现这一点吗?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    您不能以直接的方式做到这一点,因为在 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)

    【讨论】:

    • 谢谢:成功了。 Float::minus 也不错。 (缺少使用数组的构造函数是复制/粘贴疏忽。)
    猜你喜欢
    • 2012-09-08
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2020-02-28
    相关资源
    最近更新 更多