[英]Array<Number>: get and set Int values without casting
I am building a Matrix class and want to be able to store Number
s in a 2d Array. 我正在构建一个Matrix类,并希望能够将
Number
存储在二维数组中。
var data: Array<Array<Number>> = Array(width, {Array(height, {0})})
This does not work because Array<Number>
and Array<Int>
are invariant. 这不起作用,因为
Array<Number>
和Array<Int>
是不变的。 I can make it work by using Array<Array<out Number>>
, but the Matrix will be immutable, and I don't want that... 我可以通过使用
Array<Array<out Number>>
来使它工作,但Matrix将是不可变的,我不希望这样......
Casting {0 as Int}
makes the compiler error go away, but this does not seem like a good idea. 将
{0 as Int}
会使编译器错误消失,但这似乎不是一个好主意。 I also want to do things like addition and I noticed that it's not possible to add Number
s: 我也想做像添加这样的事情,我注意到它不可能添加
Number
s:
var n: Number = 1
n + 1 // does not work
So how could I solve this problem? 那么我怎么能解决这个问题呢? And why exactly can I not add two
Number
s? 为什么我不能添加两个
Number
?
Number is an abstract class and does not define anything for addition. Number是一个抽象类,不会为添加定义任何内容。 And since there's no defined method for adding the numbers, you can't do
numberInstane + otherNumberInstance
. 由于没有用于添加数字的已定义方法,因此您无法执行
numberInstane + otherNumberInstance
。 You can, however, create an operator function for it: 但是,您可以为它创建一个运算符函数:
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
}
}
Note that this only applies to addition. 请注意,这仅适用于添加。 The rest of the functions would follow the same pattern, but replacing the operator (here it's
+
) and the name of the function (here it's plus
). 其余的函数将遵循相同的模式,但替换运算符(这里是
+
)和函数的名称(这里是plus
)。
As mer msrd0's comment, the above would result in 1 + 1.5 being 2, because it rounds down. 作为mer msrd0的评论,上面会导致1 + 1.5为2,因为它向下舍入。 Kotlin supports adding number types across each other, which ends up with this slightly horrid solution:
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
}
}
The nested when-statement helps autocasting the values, which is necessary since Number isn't a specific known class. 嵌套的when语句有助于自动更新值,这是必需的,因为Number不是特定的已知类。 There might be a better solution though, but without knowing the specific type.
可能有更好的解决方案,但不知道具体的类型。 The extension function is mostly just auto-casting based on the type, but there can't be a single variable because it would need to be defined as a Number to accept all the types, and since there are two vars where both need proper casting based on the passed type, it ends up being slightly messy.
扩展函数大多只是基于类型的自动转换,但是不能有单个变量,因为它需要被定义为一个数字来接受所有类型,并且因为有两个vars都需要适当的转换根据传递的类型,它最终会有点凌乱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.