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 写成中缀形式。


一元操作符(无参数)

表达式实际转换为
+aa.unaryPlus()
-aa.unaryMinus()
!aa.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 + ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.rem(b)
a..ba.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 bb.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] = ba.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 += ba.plusAssign(b)
a -= ba.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 == ba?.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 > ba.compareTo(b) > 0
a < ba.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 提供的一个强大工具,可以让你的代码更具可读性与表现力。你只需满足函数命名、修饰符和签名的基本要求,就能为你的类型添加直观且易用的运算符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值