Kotlin重载运算符

什么是运算符重载?
简单来说,就是Kotlin通过调用自己代码中定义特定的函数名的函数(成员函数或者扩展函数),并且用operator修饰符标记,来实现特定的语言结构,例如如果你在一个类上面定义了一个特定函数命名plus的函数,那么按照Kotlin的约定,可用在这个类的实例上使用+运算符,下面是代码。

用于重载运算符的所有函数都必须使用operator关键字标记。

// 一个简单的数据类
data class Foo(val x: Int, val y: Int) {
    operator fun plus(other: Foo) : Foo = Foo(x + other.x, y + other.y)
}

fun main(args: Array) {
    // 使用的时候
    val f1 = Foo(10, 20)
    val f2 = Foo(30, 40)
    // 直接用+运算符代替plus函数,事实上会调用plus函数
    println(f1 + f2) // 打印内容为Foo(x=40, y=60)
}

那么Java如何调用运算符函数呢?
重载的运算符实际上是被定义成一个函数,Java调用Kotlin运算符就跟调用普通函数一样调用就行。
重载算术运算符
算术运算符包括二元运算符、复合赋值运算符、一元运算符,当Kotlin在给一个集合添加元素的时候,是调用add方法,用到重载的话,我们就可以直接用+=来进行这个操作,就会显得更加的优雅。。。

fun Any.println() = println(this)

fun main(args: Array) {
    val list = arrayListOf(1, 2 ,3)
    list.println() // 打印[1, 2, 3]
    list.add(4)
    list.println() // 打印[1, 2, 3, 4]
    list += 5
    list.println() // 打印[1, 2, 3, 4, 5]
}

fun main(args: Array) {
    var f1 = Foo(1, 2)
    f1 += Foo(3, 4)
    f1.println() // 打印Foo(x=4, y=6)
}

上面的+=等同于f1 = f1 + Foo(3, 4),这些操作当然是只对可变变量有效的。
默认情况下,复合赋值运算符是可以修改变量所引用的对象,同时重新分配引用,但是在将一个元素添加到一个可变集合的时候,+=是不会重新分配引用的:
fun main(args: Array) {
    val list = mutableListOf()
    list += 42
    list.println() // 打印[42]
}

同样我们可以对复合赋值运算符进行重载,同样可以定义多个同名,但是参数不一样的方法:
operator fun MutableCollection.plusAssign(element: Int) {
    this.add(element - 1)
}

fun main(args: Array) {
    val list = mutableListOf()
    list += 42
    list.println() // 打印[41]
}

如果在plus和plusAssign两个函数同时被定义且适用,那么编译器就会报错,最好在设计新类的时候保持(可变性)一致,尽量不同时定义plus和plusAssign运算。如Foo类是不可变的,那么只提供plus运算,如果一个类是可变的,如构造器,那么只需提供plusAssign和类似的运算就够了

你可能感兴趣的:(Kotlin重载运算符)