为什么Kotlin的数字类运算符会丢失?

时间:2019-08-07 10:48:36

标签: kotlin language-design

在Kotlin中,Number类型听起来非常有用:一种在需要数字的地方使用的类型。

但是,当我实际使用它时,我很快注意到它非常没用:我不能在这些数字上使用任何运算符。一旦需要对它们进行处理,就需要显式转换它们(甚至用于比较)。

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

考虑到这一点,我注意到实现Number.plus(n: Number): Number可能很棘手,因为n的类型可能与this不同。
另一方面,我检查的所有Number子类型中的such implementations do exist。当然,如果我要键入1 + 1.2

,则必须输入它们。

对我来说,结果是每次使用电话号码时我都要打{{1​​}}。这使得代码难以阅读(将Int.plus(d: Double): Double.toDouble()进行比较)。

是否有任何技术上的原因导致a.toDouble() < b.toDouble()中省略了运算符?

1 个答案:

答案 0 :(得分:0)

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

您如何比较任意 Number 类的实例? Kotlin 可以使用 toDouble() 实现 compare 方法;但是,这在相等/精度方面存在问题:您如何将 BigDecimalDouble 进行比较?在 toDouble() 上使用 BigDecimal 可能会失去精度,并且使用此方法可能会认为两个(实际上不同的)BigDecimal 是相等的。 当您开始假设一种或两种类型是由库提供的,而您无法对精度等做出假设时,情况会变得更糟。

在 Java 中,Number type is not Comparable either。 此外,some Number values like NaN might not be comparable at all

如果您需要一个 Number 进行比较,您可以轻松实现您自己的 compareTo 方法作为扩展函数。但是,这有一些额外的限制,因为大多数 Number 子类型实现了 Comparable,并且扩展函数将失去该实现。

此答案的功劳归于 Roland,我只是将他的评论(参见问题)扩展到了答案中。