在Kotlin中,通过关键字operator支持运算符重载。这样可以为用户定义的类型定义标准运算符(+、-、*、[]、==等)的自定义逻辑:
operator修饰符。示例:
data class Vec2(val x: Int, val y: Int) { operator fun plus(other: Vec2) = Vec2(x + other.x, y + other.y) } val a = Vec2(1,2) val b = Vec2(2,3) val c = a + b // 调用operator fun plus
细节和最佳实践:
==和equals必须一致)。运算符
==的重载与方法equals()的重写有什么区别?
**回答:**Kotlin中的运算符==始终调用方法equals()(在此之前检查null)。如果您定义了operator fun equals(other: Any?): Boolean,则运算符==将始终使用该方法。无法让==和equals()的工作方式不同。
data class Point(val x: Int, val y: Int) { override operator fun equals(other: Any?): Boolean { ... } } val a = Point(1,2) val b = Point(1,2) println(a == b) // 调用 a.equals(b)
历史
在没有明确语义的情况下重载运算符compareTo:
在Point类中定义了operator fun compareTo以便能够用于排序。但是“更大”和“更小”没有明确的意义,不同的团队成员编写了不同的逻辑。结果是,在排序集合时造成了混乱的bug。
历史
忘记了对称性运算符对于双向类型的重要性:
开发者实现了operator fun plus(a: Matrix, b: Vector): Matrix,但没有确保Vector + Matrix的工作,因为没有实现对称函数。结果是表达式vector + matrix无法编译,只有matrix + vector工作。这在代码的许多部分引发了错误。
历史
错误的重载运算符get:
开发者创建了一个自定义类,重载了operator fun get(index: Int): Foo。未添加越界检查——尝试访问不存在的元素会返回带有无效字段的对象,而不是抛出异常——这导致在业务逻辑中出现了“隐形”错误。