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

相关推荐
yzpyzp17 小时前
如果后台的Long类型的数据返回是null,那么Android客户端的数据bean的kotlin的Long类型的字段接受到数据后是null空指针吗?
android·kotlin
xvch20 小时前
Kotlin 2.1.0 入门教程(二十五)类型擦除
android·kotlin
有点感觉2 天前
Android级联选择器,下拉菜单
kotlin
zhangphil2 天前
Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(1)
android·kotlin
xvch3 天前
Kotlin 2.1.0 入门教程(二十三)泛型、泛型约束、协变、逆变、不变
android·kotlin
xvch4 天前
Kotlin 2.1.0 入门教程(二十四)泛型、泛型约束、绝对非空类型、下划线运算符
android·kotlin
zhangphil5 天前
Android Coil ImageLoader MemoryCache设置Key与复用内存缓存,Kotlin
android·kotlin
mmsx5 天前
kotlin Java 使用ArrayList.add() ,set()前面所有值被 覆盖 的问题
android·开发语言·kotlin
lavins5 天前
android studio kotlin项目build时候提示错误 Unknown Kotlin JVM target: 21
jvm·kotlin·android studio
面向未来_5 天前
JAVA Kotlin Androd 使用String.format()格式化日期
java·开发语言·kotlin