运算符重载(operator 关键字)
1. 运算符重载的概念
Kotlin 允许通过 operator 关键字为自定义类重载预定义的运算符(如 +、-、*、/ 等),使其支持类似内置类型的操作语法。
核心思想:将运算符映射为特定名称的成员函数或扩展函数。
2. 可重载的运算符及对应函数名
Kotlin 为每种运算符规定了固定的函数名,重载时需严格匹配:
| 运算符 | 函数名 | 示例表达式 | 等效调用 |
|---|---|---|---|
+ | plus | a + b | a.plus(b) |
- | minus | a - b | a.minus(b) |
* | times | a * b | a.times(b) |
/ | div | a / b | a.div(b) |
% | rem | a % b | a.rem(b) |
++ | inc | a++ | a.inc() |
-- | dec | a-- | a.dec() |
== | equals | a == b | a.equals(b) |
> | compareTo | a > b | a.compareTo(b) |
[] | get/set | a[i] | a.get(i) |
in | contains | a in b | b.contains(a) |
3. 实现运算符重载的步骤
3.1 定义重载函数
在类中声明指定名称的成员函数,并用 operator 修饰:
data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}
3.2 使用重载运算符
val p1 = Point(1, 2)
val p2 = Point(3, 4)
println(p1 + p2) // 输出: Point(x=4, y=6)
4. 常见应用场景
4.1 数学运算
operator fun Point.times(scale: Int): Point {
return Point(x * scale, y * scale)
}
val p = Point(2, 3) * 3 // Point(x=6, y=9)
4.2 集合操作
operator fun List<Int>.get(range: IntRange): List<Int> {
return subList(range.start, range.endInclusive + 1)
}
val list = listOf(1, 2, 3, 4, 5)
println(list[1..3]) // 输出: [2, 3, 4]
4.3 自定义比较
operator fun Point.compareTo(other: Point): Int {
return (x + y).compareTo(other.x + other.y)
}
println(Point(1, 2) > Point(0, 3)) // 输出: false
5. 注意事项
- 不可自定义新运算符:只能重载 Kotlin 预定义的运算符。
- 保持语义一致性:重载的运算符行为应符合直觉(如
+不应实现减法逻辑)。 - 扩展函数重载:可通过扩展函数为第三方库添加运算符支持。
- 性能考虑:避免在频繁调用的运算符中实现复杂逻辑。
6. 完整示例
data class Vector(val x: Double, val y: Double) {
operator fun plus(v: Vector) = Vector(x + v.x, y + v.y)
operator fun minus(v: Vector) = Vector(x - v.x, y - v.y)
operator fun times(scalar: Double) = Vector(x * scalar, y * scalar)
}
fun main() {
val v1 = Vector(1.0, 2.0)
val v2 = Vector(3.0, 4.0)
println(v1 + v2) // Vector(x=4.0, y=6.0)
println(v1 * 2.5) // Vector(x=2.5, y=5.0)
}
最佳实践:运算符重载能显著提升代码可读性,但过度使用可能导致代码难以理解,建议仅在语义明确的情况下使用。
