Kotlin,关于Number的通用操作

时间:2016-11-14 10:59:32

标签: generics kotlin

我有以下

abstract interface Vec2t<T : Number> {    
    var x: T
    var y: T
}

data class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>

我有一个接口,我定义了几个操作,例如:

interface fun_vector2_common {

    fun abs(res: Vec2, a: Vec2): Vec2 {
        res.x = glm.abs(a.x)
        res.y = glm.abs(a.y)
        return res
    }
}

是否可以通过使用泛型来实现,让我们说abs

interface fun_vector2_common<T : Number> {

    fun abs(res: Vec2t<T>, a: Vec2t<T>): Vec2t<T> {
        res.x = glm.abs(a.x)  // error
        res.y = glm.abs(a.y)  // error
        return res
    }
}

然后将调用基于类型的相应glm.abs()

上面的代码失败了,因为它显然需要glm.abs(n: Number)

1 个答案:

答案 0 :(得分:5)

不幸的是there's no clean way to have generic abs function。您可以使用以下abs定义来处理它:

object glm {
    fun <T : Number> abs(x: T): T {
        val absoluteValue: Number = when (x) {
            is Double -> Math.abs(x)
            is Int -> Math.abs(x)
            is Float -> Math.abs(x)
            is BigDecimal -> x.abs()
            is BigInteger -> x.abs()
            else -> throw IllegalArgumentException("unsupported type ${x.javaClass}")
        }
        @Suppress("UNCHECKED_CAST")
        return absoluteValue as T
    }
}

这可以在您的上下文中使用:

fun abs(res: Vec2, a: Vec2): Vec2 {
    res.x = glm.abs(a.x)
    ...
}