kotlin - 为什么 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
?
解决方案
问题在于compareTo
方法的实现。虽然一开始添加它听起来合理且容易,但问题在于细节:
您如何将任意Number
类的实例相互比较?toDouble()
Kotlin 可以使用;实现比较方法 但是,这在相等/精度方面存在问题:您如何将 aBigDecimal
与 a进行比较Double
?使用toDouble()
onBigDecimal
可能会失去精度,并且使用此方法可能会认为两个(实际上不同的)BigDecimal
s 相等。当您开始假设一种或两种类型由库提供时,混乱会变得更糟,因为您无法对精度等做出假设。
在 Java 中,Number
类型也不Comparable
是. 此外,某些Number
值NaN
可能根本无法比较。
如果您需要Number
比较,您可以轻松实现自己的compareTo
- 方法作为扩展功能。但是,这有一些额外的限制,因为大多数Number
子类型都实现Comparable
了,并且扩展功能将失去该实现。
这个答案的功劳归于Roland,我只是将他的评论(见问题)扩展为答案。
推荐阅读
- javascript - 我不断收到未处理的承诺拒绝
- c# - 调用保存在字符串变量中的实例方法
- ios - 未找到“GoogleSignIn/GoogleSignIn.h”文件
- c# - 是否有任何方法可以通过 ASP.NET Core 中的 SQL 注入绕过存储过程、参数化查询、ORM(实体框架)?
- javascript - 如何根据从字符串数组中求和的对应值返回字符串
- python - __init__() 缺少 1 个必需的位置参数,它将 self 作为参数读取
- pandas - 根据列名在数据框中放置值
- nlp - 使用 Word2vec 模型注释词汇表
- java - 为什么 MySQL 结果被截断?
- c++ - C++ - 对导致奇怪行为的类使用析构函数