为什么 Kotlin 的 Number 类缺少运算符?

Qw3*_*3ry 5 language-design kotlin

在 Kotlin 中,该Number类型听起来非常有用:每当我需要数字时就可以使用的类型。

然而,当实际使用它时,我很快发现它毫无用处:我无法对这些数字使用任何运算符。一旦我需要对它们做一些事情,我就需要显式地转换它们(即使是为了比较)。

为什么语言设计者选择不在规范中包含运算符Number

考虑到这一点,我注意到实现起来可能很棘手Number.plus(n: Number): Number,因为n可能与 属于不同的类型this
另一方面,这样的实现确实存在于我检查的所有Number子类型中。当然,如果我想输入,它们是必要的1 + 1.2,这会调用Int.plus(d: Double): Double

.toDouble()对我来说,结果是每次使用号码时都必须拨打。这使得代码难以阅读(a.toDouble() < b.toDouble()与相比a < b)。

是否有任何技术原因导致运算符被省略Number

Qw3*_*3ry 0

问题在于该compareTo方法的实现。虽然一开始就添加它听起来合理且容易,但问题在于细节:

您如何比较任意Number类的实例?Kotlin 可以使用以下方式实现比较方法toDouble():然而,这在相等/精度方面存在问题:您如何比较 aBigDecimal与 a Double?使用toDouble()onBigDecimal可能会失去精度,并且使用此方法可能会认为两个(实际上不同的)BigDecimal s 是相等的。当您开始假设一种或两种类型由库提供时,混乱会变得更糟,而您无法对精度等做出假设。

在 Java 中,Number类型也不Comparable. 此外,某些NumberNaN可能根本不具有可比性

如果您需要Number具有可比性,您可以轻松实现自己的compareTo方法作为扩展函数。不过,这有一些额外的限制,因为大多数Number子类型都实现Comparable,并且扩展函数将在该实现中失败。

这个答案归功于罗兰,我只是将他的评论(参见问题)扩展为答案。