【Kotlin】运算符函数、解构函数、中缀函数

1 一元运算符函数

1.1 符号和函数

符号 函数
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.dec()
a-- a.inc()

1.2 案例

Kotlin 复制代码
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 案例

Kotlin 复制代码
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 案例

Kotlin 复制代码
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 案例

Kotlin 复制代码
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 案例

Kotlin 复制代码
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 符号和函数

符号 函数
ai a.get(i)
ai, j a.get(i, j)
ai_1, ..., i_n a.get(i_1, ..., i_n)
ai = b a.set(i, b)
ai, j = b a.set(i, j, b)
ai_1, ..., i_n = b a.set(i_1, ..., i_n, b)

3.2.2 案例

Kotlin 复制代码
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 接口

Kotlin 复制代码
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 函数

Kotlin 复制代码
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 解构属性

Kotlin 复制代码
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表达式

Kotlin 复制代码
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)。

Kotlin 复制代码
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】运算符函数、解构函数、中缀函数

相关推荐
Refrain_zc1 小时前
Android 音视频通话核心二 —— 视频编码详解记录
kotlin
Refrain_zc3 小时前
Android 音视频通话核心二 —— 音频解码详解记录
kotlin
Refrain_zc4 小时前
Android 音视频通话核心二 —— 音频编码详解记录
kotlin
QING6187 小时前
如何使用Compose 绘制提升性能 —— 新手指南
kotlin·android jetpack·canvas
Refrain_zc7 小时前
Android 音视频通话核心 —— MediaCodec H.264 硬编码,SPS/PPS 合并与动态码率,视频编码全解析
kotlin
plainGeekDev7 小时前
Fragment 手动跳转 → Navigation 组件
android·java·kotlin
plainGeekDev7 小时前
XML 主题 → Compose Material3 主题
android·java·kotlin
Kapaseker8 小时前
Rust 是如何干掉空指针的
rust·kotlin
消失的旧时光-19439 小时前
Kotlin 协程设计思想(四):launch、async、withContext 到底有什么区别?
java·kotlin·async·launch·withcontext·deferred
修行者对6669 小时前
Kotlin学习笔记(1)
kotlin