Kotlin运算符重载

Kotlin 是一种适应你编程风格的语言。它允许你自定义运算符的实现,从而使代码更简洁、可读性更高。

在本主题中,你将学习如何为自定义数据类型定义自己的运算符实现。


运算符重载(Operator Overloading)

Kotlin 允许你为某些类型定义自定义运算符。这些运算符具有预定义的符号表示(如 ++=)以及优先级。要定义自定义运算符,需满足以下条件:

  1. 为对应类型提供一个具有特定名称的成员函数或扩展函数

  2. 该类型将作为二元操作中的左操作数类型,或一元操作中的参数类型

  3. 函数必须用 operator 关键字修饰


示例 1:一元操作符重载(取反)

operator fun String.unaryMinus() = this.reversed()

fun main() {
    val name = "Kotlin"
    println(-name) // 输出:niltoK
}

解释:这里定义了字符串的取反操作 -,行为是字符串反转。-name 实际会调用 name.unaryMinus()


示例 2:中缀表达式 + 运算符

infix operator fun String.times(n: Int) = this.repeat(n)

fun main() {
    val s = "Kotlin"
    println(s * 3) // 输出:KotlinKotlinKotlin
}

解释:这里定义了字符串 * 整数的操作,即重复字符串。你也可以使用 s times 3 写成中缀形式。


一元操作符(无参数)

表达式 实际转换为
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.inc()
a-- a.dec()
operator fun Pair<Int, Int>.unaryMinus() = Pair(-first, -second)
operator fun Pair<Int, Int>.inc() = Pair(first + 1, second + 1)

fun main() {
    var p = Pair(1, 2)
    println(-p) // 输出:(-1, -2)
    println(++p) // 输出:(2, 3)
}

二元操作符(两个参数)

表达式 实际转换为
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.rem(b)
a..b a.rangeTo(b)
operator fun Pair<Int, Int>.plus(other: Pair<Int, Int>) = 
    Pair(first + other.first, second + other.second)

fun main() {
    val p1 = Pair(1, 2)
    val p2 = Pair(3, 4)
    println(p1 + p2) // 输出:(4, 6)
}

in 运算符

表达式 实际转换为
a in b b.contains(a)
a !in b !b.contains(a)
operator fun Pair<Int, Int>.contains(n: Int) = n in first..second

fun main() {
    val p = Pair(1, 2)
    println(1 in p) // 输出:true
}

下标运算符 []

表达式 实际转换为
a[i] a.get(i)
a[i] = b a.set(i, b)
operator fun Pair<Int, Int>.get(n: Int) = when (n) {
    0 -> first
    1 -> second
    else -> throw IndexOutOfBoundsException()
}

fun main() {
    val p = Pair(1, 2)
    println(p[0]) // 输出:1
    println(p[1]) // 输出:2
}

函数调用运算符 ()

表达式 实际转换为
a() a.invoke()
a(i) a.invoke(i)
operator fun Pair<Int, Int>.invoke(newLine: Boolean) {
    print("($first, $second)")
    if (newLine) println()
}

fun main() {
    val p = Pair(1, 2)
    p(true) // 输出:(1, 2)
}

复合赋值运算符 +=-=

表达式 实际转换为
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
operator fun StringBuilder.plusAssign(other: String) {
    this.append(other)
}

fun main() {
    val name = StringBuilder("Kotlin")
    name += " is awesome"
    println(name) // 输出:Kotlin is awesome
}

相等与不相等 ==!=

表达式 实际转换为
a == b a?.equals(b) ?: (b === null)
a != b !(a?.equals(b) ?: (b === null))
class Point(val x: Int, val y: Int) {
    override fun equals(other: Any?): Boolean {
        return other is Point && other.x == x && other.y == y
    }
}

fun main() {
    val p1 = Point(1, 2)
    val p2 = Point(1, 2)
    println(p1 == p2) // 输出:true
}

比较运算符(需要实现 compareTo()

表达式 实际转换为
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
class Point(val x: Int, val y: Int) : Comparable<Point> {
    override fun compareTo(other: Point): Int {
        return if (x == other.x) y.compareTo(other.y) else x.compareTo(other.x)
    }
}

fun main() {
    val p1 = Point(1, 2)
    val p2 = Point(1, 2)
    println(p1 < p2) // 输出:false
    println(p1 <= p2) // 输出:true
}

总结

运算符重载是 Kotlin 提供的一个强大工具,可以让你的代码更具可读性与表现力。你只需满足函数命名、修饰符和签名的基本要求,就能为你的类型添加直观且易用的运算符。

你可能感兴趣的:(kotlin,开发语言,android)