如何在 Kotlin 中(强制)重载整数的 plus?

Dim*_*ims 3 operator-overloading addition kotlin

我想让plus它变得比加法更有意义。例如,为计算图创建惰性表达式。不幸的是,类扩展不能覆盖成员函数。将打印以下代码3

operator fun Int.plus(other: Int) = listOf(this, other)

fun main() {
    println( 1 + 2 )
}
Run Code Online (Sandbox Code Playgroud)

是否可以强制覆盖?

Swe*_*per 7

不,这是不可能的。1 + 2降低为1.plus(2),并且编译器如何找到合适的方法有一个明确定义的顺序plus规格:

如果调用正确,则对于f具有类型显式接收器e 的可调用对象T,将分析以下集合(按给定顺序):

  1. f命名为 type 的非扩展成员可调用项T
  2. 名为 的扩展可调用对象f,其接收者类型U符合 type T,在当前作用域及其向上链接的作用域中,按作用域的大小排序(最小的在前),不包括包作用域;
  3. [...]

[...]

在分析这些集合时,会选择包含任何适用的可调用对象的第一个集合进行 C 级分区,这为我们提供了结果重载候选集。

因此,总是先找到plus在 中声明的方法,然后搜索就停止在那里。Int您定义的任何扩展名都将被忽略。

假设,如果内置函数Int.plus是隐式导入的扩展函数,那么您的代码就会起作用!隐式导入的扩展在该列表中排名第六:)

我针对这种情况的解决方法是使用“通过添加反引号来声明几乎任何名称的函数”功能:

infix fun Int.`+`(other: Int) = listOf(this, other)

fun main() {
    println( 1 `+` 2 )
}
Run Code Online (Sandbox Code Playgroud)

这对于某些具有保留字符(如方括号、尖括号、斜杠和点)的名称不起作用(不是详尽的列表)。