根据与 Java 中运算符的区别,Kotlin 中的运算符可以分为四类:

  1. 与 Java 中完全相同的,如加减乘除等基本数学运算等;

  2. Java 中有,但是用途不同的,比如冒号;

  3. Java 中有而 Kotlin 中没有的,重点 ;

  4. Java 中没有而 Kotlin 中有的,重点

1. 操作符重载的概念

什么是操作符重载?让我们回想一下 Java 学习时涉及到的 多态 概念,对于一个对象,我们并不在乎它是什么类型,只关注特定的行为,让程序在执行的时候根据对象的实际类型执行具体的实现方法,这就是多态,它让我们摆脱了类型的束缚,做到面向 行为 编程。

理解了多态的概念,就能理解操作符重载。举个例子,同样是一个 + 号,用在两个数字之间表示加法,用在字符串之间则表示将它们连接成一个新字符串,编译器怎么将同一个加号识别为不同的行为呢?我们可以让这些数据类型使用名称相同的函数 重载 + 号这个运算符,编译器在遇到 + 号时会自动把它理解为执行这个函数,然后根据不同的数据类型执行不同的操作。

对于 Kotlin 来说,所有重载了运算符的函数都要用 operator 关键字标记。比如,Kotlin 中规定 + 号应该重载为 plus() 函数,所有基础类型都重载这个函数,执行 a + b 实际就是执行 a.plus(b),对于 Int.plus() 函数,它执行的就是加法,对于 String.plus() 函数,它执行的就是字符串连接。

所有的 Kotlin 操作符都是通过特定名称的函数重载实现的,具体的重载方法我们会结合具体的操作符讲解。

2. Kotlin 中与 Java 完全相同的运算符

这一部分我们就简单给出运算符与重载函数吧:

v2-0ea552dcce088afebd4a967474478180_b.pn

3. Kotlin中与 Java 使用有差异的运算符

主要是两个:== / != 和 []

  1. == 和 !=

    我们先看一下这两个运算符的重载:
    v2-6d50b3ed393cc31f059b9d7808831454_b.pn

    a?.equals(b) ?: (b===null) 这个表达式,用 Java 写出来是这样的:

    if(a != null){
      return a.equals(b);}else{
      return b == null;}

    可以看到,它实际上调用的是 equals 方法来比较两个元素是否 对象相等,而不是 Java 中的比较 引用相同

    如果需要比较两个对象的引用是否相同,可以使用 === 和 !== 操作符,它们与 Java 中的== 和 != 是一样的。

  2. []

    这个运算符的重载:
    v2-bd53a6f478fcdbf721933ce87ba54db9_b.pn

    与 Java 中的不同之处在于,Kotlin 中这个运算符不仅可以用在 数组 变量后,也可以用在集合 变量后,可以方便地 调用和操作 数组和集合中的元素。

4. Java 中有而 Kotlin 中没有的运算符

与 Java 相比,Kotlin 抛弃了类 C 风格的 位运算符,只是定义了几个函数:

v2-4c76a60fe19468245f2000d2a2f4a214_b.pn

对于 <<=、>>=、>>>= 这三个赋值操作符,Kotlin 中没有与之对应的函数。

中缀表示法 是 Kotlin 定义的一种特殊的函数调用方式,标记为 infix ,并且只有一个参数的扩展函数或成员函数,可以使用这种表示方法。

5. Java 中没有而 Kotlin 中有的运算符

  1. is 和 !is

    这两个运算符相当于 Java 中的 instanceof 运算符,用于检查对象是否是某个类的实例。

  2. in 和 !in

    a in b 重载为 b.contains(a),用于检查 a 是否是 b 内的元素,这里的 b 可以是数组、集合和区间。这个运算符还可以用在 for 循环中,用来遍历 b 中的元素:

    val b = arrayOf(1, 2, 3)for(a in b) println(a)
  3. ..

    a .. b 重载为 a.rangeTo(b),返回一个从 a 到 b 的 区间,a 和 b 这两个边界也包含在内。这里的 a 和 b 要求都是整数,而且 a <= b。

    使用区间控制循环次数,要比 Java 和 C 中的方法更加方便清晰:

    for(i in 1..10) println(i) //输出从 1 到 10 的整数