相等性判断
在 Kotlin 开发中,理解相等性至关重要。我们通常遇到两种情况:一种是对象内容的'结构相等',另一种是对象身份的'引用相等'。
结构相等
日常使用的 == 和 != 操作符实际上是在检查结构相等。编译器会将 a == b 展开为如下逻辑:
a?.equals(b) ?: (b === null)
这意味着如果 a 不为空,它会调用 equals(Any?) 方法;如果 a 为空,则直接判断 b 是否也为空。特别需要注意的是,当你拿一个变量去和 null 比较(例如 a == null)时,Kotlin 会自动将其视为引用比较 a === null,这样既安全又高效。
引用相等
如果你需要严格判断两个变量是否指向堆内存中的同一个对象实例,请使用 === 和 !==。只有当 a 和 b 指向同一对象时,a === b 才返回 true。
对于基本数据类型(如 Int),== 比较的是数值大小,而 === 比较的是引用地址。虽然在 Kotlin 的小整数缓存机制下,某些情况下两者的结果可能碰巧一致,但从语义上讲,它们有着本质的区别。
浮点数比较
处理 Float 或 Double 时,Kotlin 遵循 IEEE 754 标准。这里有两个细节容易踩坑:
NaN不等于NaN(即NaN == NaN为 false)。0.0和-0.0被视为不相等。
这些规则在处理科学计算或金融数据时需要格外留意。

