Kotlin进阶之相等、操作符重载

来源:互联网 发布:淘宝宝贝上架编辑技巧 编辑:程序博客网 时间:2024/06/07 16:01

相等

Koltin有两种相等比较

  • 引用相等(指向同一个对象的引用)
  • 结构相等(equals())

引用相等

使用===(!==)操作符检查引用相等。如果a和b指向相同对象,则a === b为true

结构相等

结构相等使用==操作符。按照规定,a == b会被翻译为:

a?.equals(b) ?: (b === null)

如果a不为空,则调用equals()函数,否则检查b引用是否为空。

非空检查a == null自动转化为a === null

操作符重载

Kotlin支持为自定义实现预定义操作符。这些操作符有固定的符号表示(如+或*)和固定的优先级。使用固定名称成员函数或扩展函数实现对应类型操作符。

重载操作符的函数要用operator修饰符标记

长远起见Koltin定义了重载不同操作的常规操作的规范。

一元操作符

表格说明了在编译器处理时,+a操作符要执行一下步骤

  • 确定a的类型,假设为T
  • 查找operator修饰的unaryPlus(),调用者为T的无参函数。(可以是成员函数或者是扩展函数)
  • 如果没有对应函数,或函数有歧义,则编译失败
  • 如果找到对应函数,并且返回类型为R,则表达式+a类型为R
与其他操作符一样,基本类型的这些操作符会自动优化,不会引入额外开销

如下面,重载一元减号操作符

data class Point(val x: Int , val y: Int)operator fun Point.unaryMinus() = Point(-x, -y)val point = Point(10, 20)println(-point)  // 输出"(-10, -20)"

自加和自减

inc()和dec()函数必须指定返回值,赋值给调用++、--操作符的变量。不应该改变调用inc()和dec()函数的对象。

编译器执行以下步骤完成后缀形式(如a++)的操作。

  • 确定a的类型,假设为T
  • 查找适应T类型,operator修饰的inc()无参函数,
  • 检查返回类型是否为T的子类

计算表达式的作用

  • 存储初始值a的临时变量a0
  • 将a.inc()赋值给a
  • 返回a0作为表达式返回值

a--步骤同a++

对于前缀形式的++a和--a编译步骤相同, 作用

  • 将a.inc()赋值给a
  • 将a的新值作为返回值

二元操作数

算数操作符

编译器值只将表中操作表达式解析为转换列中形式。

rem操作符从Kotlin 1.1版本起替换1.1之前的mod操作符

范例

如下面的Counter类复写+操作符,完成对指定值的累加操作

data class Counter(val dayIndex: Int){    operator fun plus(increment: Int): Counter{        return Counter(dayIndex + increment)    }}

in操作符

in和!in操作符处理步骤相同,但是转换后的参数相反。

索引访问操作符

方括号转换为相同参数数量的get和set函数

Invoke操作符

括号转换为相同数量参数的invoke函数。

增强赋值

对于赋值操作符(如a += b),编译器执行以下步骤

  • 如果提供表中右侧对应的函数
    • 如果有对应的二元函数(如plusAssign()对应的plus()),则编译出错(歧义)
    • 返回值为Unit,否则出错
    • 生成a.plusAssign(b)代码


  • 否则尝试为a = a + b生成代码(包括类型检查:a + b的类型必须为a的子类)
在Kotlin中,赋值不是表达式

相等与不等操作符

===和!==(一致性检查)不可以进行重载,所以不存在规定。

==操作符为特殊情况:转换为屏蔽null值的复杂表达式。null == null值为true,且非空x的x == null值为false,不调用x.equals()

比较操作符

所有比较操作符转换为调用compareTo,返回类型为Int

中缀调用命名函数

Koltin支持使用中缀函数调用模仿自定义中缀操作符。

原创粉丝点击