Arrays 数组<;编号>;:无需强制转换即可获取和设置Int值

Arrays 数组<;编号>;:无需强制转换即可获取和设置Int值,arrays,generics,kotlin,invariance,Arrays,Generics,Kotlin,Invariance,我正在构建一个矩阵类,希望能够在2d数组中存储Numbers var data: Array<Array<Number>> = Array(width, {Array(height, {0})}) 那么我该如何解决这个问题呢?为什么我不能添加两个Numbers?Number是一个抽象类,不定义任何可添加的内容。因为没有定义的方法来添加数字,所以不能执行numberInstane+otherNumberInstance。但是,您可以为其创建运算符函数: infix ope

我正在构建一个矩阵类,希望能够在2d数组中存储
Number
s

var data: Array<Array<Number>> = Array(width, {Array(height, {0})})

那么我该如何解决这个问题呢?为什么我不能添加两个
Number
s?

Number是一个抽象类,不定义任何可添加的内容。因为没有定义的方法来添加数字,所以不能执行
numberInstane+otherNumberInstance
。但是,您可以为其创建运算符函数:

infix operator fun Number.plus(other: Number) : Number{
    return when (this) {
        is Double -> this + other.toDouble()
        is Int -> this + other.toInt()
        is Long -> this + other.toLong()
        is Float -> this + other.toFloat()
        is Short -> this + other.toShort()
        is Byte ->  this + other.toByte()
        else -> 0
    }
}
请注意,这仅适用于添加。其余函数将遵循相同的模式,但会替换操作符(这里是
+
)和函数名(这里是
plus


正如mer msrd0的评论,上面的结果是1+1.5等于2,因为它是四舍五入的。Kotlin支持在彼此之间添加数字类型,最终得到的解决方案有点可怕:

infix operator fun Number.plus(other: Number) : Number{

    when {
        this is Double -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Int -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Long -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Float -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Short -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Byte -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        else -> return 0
    }
}

嵌套的when语句有助于自动广播值,这是必要的,因为Number不是特定的已知类。虽然可能有更好的解决方案,但不知道具体的类型。扩展函数主要是基于类型的自动转换,但不能有一个变量,因为它需要定义为一个数字来接受所有类型,并且由于有两个变量都需要基于传递的类型进行正确转换,因此最终会有点混乱。

好的,我明白了。。所以我想这样做是可行的,但它似乎不是一个干净的解决方案:/@Tagas这是一个有点粗糙的解决方案,但它是不需要手动强制转换的最简单的选择。虽然您的解决方案可能有效,但有人可能会说
1+1.5
应该是
2.5
,虽然您的plus运算符函数将返回
2
,因为您只检查
this
的类型,而不是
other
@msrd0,但您是对的。我编辑了我的答案(尽管这是一个有点混乱的解决方案)
infix operator fun Number.plus(other: Number) : Number{

    when {
        this is Double -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Int -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Long -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Float -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Short -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        this is Byte -> {
            return when(other){
                is Double -> this + other
                is Int -> this + other
                is Long -> this + other
                is Float -> this + other
                is Short -> this + other
                is Byte ->  this + other
                else -> 0
            }
        }
        else -> return 0
    }
}