【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 符号和函数

符号 函数
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 案例

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

相关推荐
Kapaseker15 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z3 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton3 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream3 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam3 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker4 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin
糖猫猫cc4 天前
Kite:两种方式实现动态表名
java·kotlin·orm·kite
如此风景5 天前
kotlin协程学习小计
android·kotlin
Kapaseker5 天前
你搞得懂这 15 个 Android 架构问题吗
android·kotlin
zh_xuan5 天前
kotlin 高阶函数用法
开发语言·kotlin