首页 > 解决方案 > 为什么 Kotlin 的 Number-class 缺少运算符?

问题描述

在 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

标签: kotlinlanguage-design

解决方案


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

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

在 Java 中,Number类型也不Comparable. 此外,某些NumberNaN可能根本无法比较

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

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


推荐阅读