Java转Kotlin:操作符重载与中缀表达式

257 阅读2分钟

操作符重载

  • Kotlin支持操作符重载
  • 仅支持重载部分官方指定的操作符
//Kotlin
import kotlin.IndexOutOfBoundsException

class Complex(var real: Double, var image: Double) {
    override fun toString(): String {
        return "${this.real} + ${this.image}i"
    }

    override fun equals(other: Any?): Boolean {
        return if (other is Complex) {
            this.real == other.real && this.image == other.image
        } else {
            false
        }
    }

    operator fun minus(other: Any?): Complex = if (other is Complex) Complex(
        this.real - other.real,
        this.image - other.image
    ) else throw IndexOutOfBoundsException()
}

operator fun Complex.plus(other: Any?): Complex = if (other is Complex) Complex(
    this.real + other.real,
    this.image + other.image
) else throw IndexOutOfBoundsException()

fun main() {
    val c1 = Complex(3.0, 5.0)
    val c2 = Complex(9.0, 15.0)
    println(c1 - c2)
    println(c2 + c2)
}

在上面的例子中,我们定义了复数Complex,重载了+操作符和-操作符,并且分别采用了常用重载方法扩展方法

总结Kotlin重载操作符的步骤如下:

  1. 确定希望重载的操作符;
  2. 判断Kotlin是否支持重载该操作符,Kotlin支持重载的操作符如下(IDE提示):

  1. 希望重载哪个操作符就使用operator关键字去定义该操作符对应的函数,例如希望重载*操作符,则定义operator fun times(arg: Any?): Any? {//TODO}
  2. 完成。

更多操作符的重载操作参考官方文档:Kotlin操作符重载

中缀表达式

看下面例子:

编译器翻译成:

我们学习过Pair,可以用A to B的形式快捷表示,其定义就是如上。

  • infix关键字开头;
  • fun关键字定义函数;
  • 上面的例子中使用了泛型,后面详解,本例中也比较易懂;
  • 因为有infix关键字,编译器知道可以将2 to 3翻译成2.to(3)

再例,为String类定义扩展方法rotate(),实现字符串的旋转:

//Kotlin
infix fun String.rotate(index: Int): String = this.substring(index) + this.substring(0, index)

fun main() {
    println("HelloWorld" rotate 5)//打印:WorldHello
    //上面的语句被编译器翻译成下面的语句
    println("HelloWorld".rotate(5))//打印:WorldHello
}