返回介绍

运算符重载

发布于 2025-03-08 18:25:16 字数 4672 浏览 0 评论 0 收藏 0

Kotlin 允许我们实现一些我们自定义类型的运算符实现。这些运算符有固定的表示,和固定的优先级。为实现这样的运算符,我们提供了固定名字的数字函数和扩展函数,比如二元运算符的左值和一元运算符的参数类型。

转换

这里我们描述了一些常用运算符的重载

一元运算符

表达式转换
+aa.plus()
-aa.minus()
!aa.not()

这张表解释了当编译器运行时,比如,表达式 +a ,是这样运行的:

决定 a 的类型,假设是 T 寻找接收者是 T 的无参函数 plus() ,比如数字函数或者扩展函数 如果这样的函数缺失或不明确,则返回错误。 如果函数是当前函数或返回类型是 R 则表达式 +aR 类型。

注意这些操作符和其它的一样,都被优化为基本类型并且不会产生多余的开销。

表达式转换
a++a.inc() + see below
a--a.des() + see below

这些操作符允许修改接收者和返回类型。

inc()/dec() shouldn’t mutate the receiver object.
By “changing the receiver” we mean the receiver-variable, not the receiver object.

编译器是这样解决有后缀的操作符的比如 a++ :

决定 a 的类型,假设是 T 寻找无参函数 inc() ,作用在接收者 T 如果返回类型是 R ,则必须是 T 的子类

计算表达式的效果是:

把 a 的初始值存储在 a0 中 把 a.inc() 的结果作用在 a 上 把 a0 作为表达式的返回值

a-- 的步骤也是一样的

++a --a 的解决方式也是一样的

二元操作符

表达式转换
a + ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.mod(b)
a..ba.rangeTo(b)

编译器只是解决了该表中翻译为列的表达式

表达式转换
a in bb.contains(a)
a !in b!b.contains(a)

in 和 !in 的产生步骤是一样的,但参数顺序是相反的。

标志转换
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] = ba.set(i, b)
a[i,j] =ba.set(i, j, b)
a[i_1, ... , i_n] = ba.set(i_1,... ,o_n,b)

方括号被转换为 get set 函数

标志转换
a(i)a.invoke(i)
a(i, j)a.invoke(i, j)
a(i_1, ... , i_n)a.invoke(i_1, ..., i_n)

括号被转换为带有正确参数的 invoke 参数

表达式转换
a += ba.plusAssign(b)
a -= ba.minusAssign(b)
a *= ba.timesAssign(b)
a /= ba.divAssign(b)
a %= ba.modAssign(b)

在分配 a+= b 时编译器是下面这样实现的:

右边列的函数是否可用 对应的二元函数(比如 plus() ) 是否也可用,不可用在报告错误 确定它的返回值是 Unit 否则报告错误 生成 a.plusAssign(b) 否则试着生成 a=a+b 代码

Note: assignments are NOT expressions in Kotlin.

表达式转换
a == ba?.equals(b) ?: b.identityEquals(null)
a != b!(a?.equals(b) ?: b.identityEquals(null))

注意 === !== 是不允许重载的

== 操作符有俩点特别:

它被翻译成一个复杂的表达式,用于筛选空值,而且 null == null 是真

它需要带有特定签名的函数,而不仅仅是特定名称的函数,下面这样:

fun equals(other: Any?): Boolean

或者用相同的参数列表和返回类型的扩展功能

标志转换
 

a > b |a.compareTo(b) > 0 a < b |a.compareTo(b) < 0 a >= b |a.compareTo(b) >= 0 a <= b |a.compareTo(b) <= 0

所有的比较都转换为 compareTo 的调用,这个函数需要返回 Int

命名函数的中缀调用

我们可以通过 中缀函数的调用 来模拟自定义中缀操作符

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文