一元操作符
一元操作符(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)
复制代码