【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】运算符函数、解构函数、中缀函数

相关推荐
Coffeeee20 小时前
Android功耗优化,哪些代码会让你的机子发热又耗电
android·架构·kotlin
Android打工仔20 小时前
Kotlin 编译器是如何把 suspend 函数变成状态机的?
kotlin
Android打工仔20 小时前
一个 suspend 函数,为什么会变成一个普通函数?
kotlin
苦瓜花2 天前
【Kotlin】初入门
android·开发语言·kotlin
Kapaseker2 天前
Rust 是如何处理异常的
rust·kotlin
冬日砥砺前行2 天前
Kotlin 协程:几个曾经被我误解的点
kotlin
plainGeekDev4 天前
libs 目录 → Gradle 依赖管理
android·java·kotlin
监督者修4 天前
从零构建 GIS 数据引擎:方案驱动架构的设计与实践
android·架构·kotlin
urkay-5 天前
Kotlin Flow分类
android·开发语言·kotlin
alexhilton5 天前
Kotlin DSL深度解析:从Gradle脚本到构建你自己的DSL
android·kotlin·android jetpack