1 一元运算符
 
1.1 符号和函数
 
| 符号 | 函数 | 
| +a | a.unaryPlus() | 
| -a | a.unaryMinus() | 
| !a | a.not() | 
| a++ | a.dec() | 
| a-- | a.inc() | 
 
1.2 案例
 
fun main() {var stu = Student("Tom", 13)println(-stu) // 打印: [moT, 31]
}class Student(var name: String, var age: Int) {operator fun unaryMinus(): Student {return Student(name.reversed(), age.toString().reversed().toInt())}override fun toString(): String {return "[$name, $age]"}
}
 
2 二元运算符
 
2.1 基础运算符
 
2.1.1 符号和函数
 
| 符号 | 函数 | 
| 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..b | a.rangeTo(b) | 
| a..<b | a.rangeUntil(b) | 
| a in b | b.contains(a) | 
| a !in b | !b.contains(a) | 
 
2.1.2 案例
 
fun main() {var stu1 = Student("Tom", 13)var stu2 = Student("Mary", 18)println(stu1 + stu2) // 打印: [TomMary, 31]
}class Student(var name: String, var age: Int) {operator fun plus(other: Student): Student {return Student(this.name + other.name, this.age + other.age)}override fun toString(): String {return "[$name, $age]"}
}
 
2.2 自增简化运算符
 
2.2.1 符号和函数
 
| 符号 | 函数 | 
| a += b | a.plusAssign(b) | 
| a -= b | a.minusAssign(b) | 
| a *= b | a.timesAssign(b) | 
| a /= b | a.divAssign(b) | 
| a %= b | a.remAssign(b) | 
 
        说明:如果类中同时定义了 plus 和 plusAssign 运算,a += b 就会产生歧义,因为 a += b 等价于 a = a + b,编译器不知道是执行 plus 函数还是 plusAssign 函数,就会编译报错,其他运算符同理。
 
2.2.2 案例
 
fun main() {var stu1 = Student("Tom", 13)var stu2 = Student("Mary", 18)stu1 += stu2println(stu1) // 打印: [TomMary, 31]
}class Student(var name: String, var age: Int) {operator fun plusAssign(other: Student): Unit {this.name += other.namethis.age += other.age}override fun toString(): String {return "[$name, $age]"}
}
 
2.3 比较运算符
 
2.3.1 符号和函数
 
| 符号 | 函数 | 
| a > b | a.compareTo(b)   > 0 | 
| a < b | a.compareTo(b)   < 0 | 
| a >= b | a.compareTo(b)   >= 0 | 
| a <= b | a.compareTo(b)   <= 0 | 
 
2.3.2 案例
 
fun main() {var stu1 = Student("Tom", 13)var stu2 = Student("Mary", 18)var res = stu1 >= stu2println(res) // 打印: false
}class Student(var name: String, var age: Int) {operator fun compareTo(other: Student): Int {return this.age - other.age}
}
 
3 括号运算符
 
3.1 小括号
 
3.1.1 符号和函数
 
| 符号 | 函数 | 
| a() | a.invoke() | 
| a(i) | a.invoke(i) | 
| a(i, j) | a.invoke(i, j) | 
| a(i_1, ..., i_n) | a.invoke(i_1, ..., i_n) | 
 
3.1.2 案例
 
fun main() {var stu = Student("Mary", 18)stu() // 打印: Maryvar age = stu(1) // 打印: aprintln(age) // 打印: 18
}class Student(var name: String, var age: Int) {operator fun invoke(): Unit {println(name)}operator fun invoke(i: Int): Int {println(name[i])return age}
}
 
3.2 中括号
 
3.2.1 符号和函数
 
| 符号 | 函数 | 
| a[i] | a.get(i) | 
| a[i, j] | a.get(i, j) | 
| a[i_1, ..., i_n] | a.get(i_1, ..., i_n) | 
| a[i] = b | a.set(i, b) | 
| a[i, j] = b | a.set(i, j, b) | 
| a[i_1, ..., i_n] = b | a.set(i_1, ..., i_n, b) | 
 
3.2.2 案例
 
fun main() {var stu = Student("Mary")println(stu[1]) // 打印: astu[1] = 'W'println(stu.name) // 打印: MWry
}class Student(var name: String) {operator fun get(i: Int): Char {return name[i]}operator fun set(i: Int, c: Char): Unit {name = name.substring(0, i) + c + name.substring(i + 1)}
}
 
4 解构函数
 
4.1 解构属性
 
fun main() {var stu = Student("Tom", 13)var (name, age) = stuprintln("$name, $age") // 打印: Tom, 13var (_, age2) = stu // 只需要部分参数, 其他参数可以使用_忽略掉
}class Student(var name: String, var age: Int) {operator fun component1() = nameoperator fun component2() = age
}
 
4.2 解构在 Lambda 表达式中的使用
 
        Lambda 表达式详细介绍见 → Lambda表达式。
 
fun main() {var stu = Student("Tom", 13)var myFun: (Student) -> Unit = {(name, age) ->println("$name, $age")}myFun(stu) // 打印: Tom, 13
}class Student(var name: String, var age: Int) {operator fun component1() = nameoperator fun component2() = age
}
 
5 中缀函数
 
        中缀函数是使用 infix 关键字标记的函数,在使用时,可以省略点和括号,如:位运算 shl 就是一个中缀函数。函数必须满足以下条件。
 
- 必须是成员函数(不是顶层函数);
- 只能有一个参数;
- 参数不能有默认值。
         中缀函数调用的优先级低于算术运算符、类型转换和 rangeTo 运算符,高于布尔运算符(&&、||、is)。
 
fun main() {var stu = Student("Tom")stu play "basketball"
}class Student(var name: String) {infix fun play(str: String): Unit {println("$name play $str")}fun test() {// play "badminton" // 编译报错this play "badminton"}
}
 
        说明: 如果在类中使用中缀函数,必须明确函数的调用方(接收器)。