[转] Kotlin - 操作符与重载

参考链接: https://juejin.cn/post/6954564315743518734

2周前 27次点击 来自 移动端

标签: Kotlin

一元操作符

一元操作符(unary operation) 有前缀操作符、递增和递减操作符等。

前缀操作符

前缀操作符放在操作数的前面,如下所示

表达式 翻译为
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()

以下是重载一元减运算符的示例:

data class Point(val x: Int, val y: Int)

operator fun Point.unaryMinus() = Point(-x, -y)

测试:

import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class OperatorDemoTest {

    @Test
    fun testPointUnaryMinus() {
        val p = Point(1, 1)
        val np = -p
        println(np)
    }
}
// Point(x=-1, y=-1)

递增和递减操作符

inc() 和 dec() 函数必须返回一个值,它用于赋值给使用 ++ 或 -- 操作的变量。前缀和后缀的表达式返回值是不同的,具体的取值如下:

表达式 翻译为
a++ a.inc()返回值是 a
a-- a.dec()返回值是 a
++a a.inc()返回值是 a+1
--a a.dec()返回值是 a-1

二元操作符

Kotlin 中的二元操作符有算术运算符、索引访问操作符、调用操作符、计算并赋值操作符、相等与不等操作符、Elvis 操作符、比较操作符、中缀操作符等。下面分别介绍。

算术运算符

Kotlin 的算术运算符有加、减、乘、除、取余、范围操作符等,如图所示:

表达式 翻译为
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.mod(b)
a..b a.rangTo(b)

自定义重载的 “+” 运算符

下面使用一个计数类 Counter 重载的 “+” 运算符来增加 index 的计数值。代码示例如下:

data class Counter(val index: Int)

operator fun Counter.plus(increment: Int): Counter {
    return Counter(index + increment)
}

测试

import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class OperatorDemoTest {
    
    @Test
    fun testCounterIndexPlus() {
        val c = Counter(1)
        val cPlus = c + 10
        println(cPlus)
    }
}
// Counter(index=11)

in操作符

in 操作符等价于 contains() 函数,如下所示。

表达式 翻译为
a in b b.contains(a)
a !in b !b.contains(a)

索引访问操作符

索引访问操作符方括号 [] 转换为调用带有适当数量参数的 get 和 set,如下所示。

表达式 翻译为
a[i] a.get(i)
a[i] = b a.set(i, b)

调用操作符

小括号调用符 () 转换为 invoke() 函数,同样带参数调用也会转换为 invoke() 函数中的参数。如下所示。

表达式 翻译为
a() a.invoke()
a(i) a.invoke(i)

计算并赋值操作符

对于赋值操作,例如 a+=b,编译器会试着生成 a=a+b 的代码(这里包含类型检查:a+b 的类型必须是 a 的子类型)。计算并赋值操作符对应的重载函数如下所示。

表达式 翻译为
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.modAssign(b)

相等与不等操作符

Koltin 中有两种类型的相等性:

  • 引用相等 === !== (两个引用指向同一对象)
  • 结构相等 == != (使用 equals 判断)
表达式 翻译为
a == b a?.equals(b) ?: (b === null)
a != b !a(a?.equals(b) ?: (b === null))

"==" 操作符有些特殊:它被翻译为一个复杂的表达式,用于筛选 null 值。意思是:如果 a 不是 null 则调用 equals(Any?) 函数并返回其值:否则(即a === null)就计算 b === null 的值并返回。 当与 null 显式比较时, a == null 会被自动转换为 a === null。

比较操作符

Kotlin 中所有的比较表达式都转换为对 compareTo() 函数的调用,这个函数需要返回 Int 值,如下所示。

表达式 翻译为
a>b a.compareTo(b) > 0
a<b a.compareTo(b) < 0
a>=b a.compareTo(b) >= 0
a<=b a.compareTo(b) <= 0

用 infix 函数自定义中缀操作符

我们可以通过自定义 infix 函数来实现中缀操作符。代码示例如下:

data class Person(val name: String, val age: Int)

infix fun Person.grow(years: Int): Person {
    return Person(name, age + years);
}

测试

@RunWith(JUnit4::class)
class InfixFunctionDemoTest {

    @Test
    fun testInfixFunction() {
        val person = Person("Jack", 20)
        println(person.grow(2)) //直接调用函数
        println(person grow(2)) // 中缀表达式调用方式
    }
} 
// Person(name=Jack, age=22)
// Person(name=Jack, age=22)

本文转自 https://juejin.cn/post/6954564315743518734,如有侵权,请联系删除。

Made with in Shangrao,China By Devler.

Copyright © Devler 2012 - 2022

赣ICP备19009883号-1