【Kotlin】运算符函数、解构函数、中缀函数
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 += stu2
println(stu1) // 打印: [TomMary, 31]
}
class Student(var name: String, var age: Int) {
operator fun plusAssign(other: Student): Unit {
this.name += other.name
this.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 >= stu2
println(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() // 打印: Mary
var age = stu(1) // 打印: a
println(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]) // 打印: a
stu[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 迭代器运算符函数
迭代器运算符即:for(item in items) 运算符,有以下两种实现方式。
- 继承 Iterator 接口,实现 hasNext 和 next 函数。
- 重载 iterator 函数,返回一个 Iterator 对象。
4.1 继承 Iterator 接口
fun main() {
var group = Group()
for (stu: Student in group) {
println(stu) // 打印: [Tom, 20]、[Mary, 18]
}
}
class Group: Iterator<Student> {
private var students = arrayOf(Student("Tom", 20), Student("Mary", 18))
private var index = 0
override operator fun hasNext() = index < students.size
override operator fun next() = students[index++]
}
class Student(var name: String, var age: Int) {
override fun toString(): String = "[$name, $age]"
}
4.2 重载 iterator 函数
fun main() {
var group = Group()
for (stu: Student in group) {
println(stu) // 打印: [Tom, 20]、[Mary, 18]
}
}
class Group {
private var students = arrayOf(Student("Tom", 20), Student("Mary", 18))
operator fun iterator(): GroupIterator = GroupIterator()
inner class GroupIterator: Iterator<Student> {
private var index = 0
override operator fun hasNext() = index < students.size
override operator fun next() = students[index++]
}
}
class Student(var name: String, var age: Int) {
override fun toString(): String = "[$name, $age]"
}
5 解构函数
5.1 解构属性
fun main() {
var stu = Student("Tom", 13)
var (name, age) = stu
println("$name, $age") // 打印: Tom, 13
var (_, age2) = stu // 只需要部分参数, 其他参数可以使用_忽略掉
}
class Student(var name: String, var age: Int) {
operator fun component1() = name
operator fun component2() = age
}
5.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() = name
operator fun component2() = age
}
6 中缀函数
中缀函数是使用 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"
}
}
说明: 如果在类中使用中缀函数,必须明确函数的调用方(接收器)。
声明:本文转自【Kotlin】运算符函数、解构函数、中缀函数。