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

How to (force) overloading of plus for integers in Kotlin?

我想让 plus 有别的意思,而不是加法。例如,为计算图创建惰性表达式。不幸的是,class 扩展不能覆盖成员函数。以下代码将打印 3:

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

fun main() {
    println( 1 + 2 )
}

是否可以强制覆盖?

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

If a call is correct, for a callable f with an explicit receiver e of type T the following sets are analyzed (in the given order):

  1. Non-extension member callables named f of type T;
  2. Extension callables named f, whose receiver type U conforms to type T, in the current scope and its upwards-linked scopes, ordered by the size of the scope (smallest first), excluding the package scope;
  3. [...]

[...]

When analyzing these sets, the first set which contains any applicable callable is picked for c-level partition, which gives us the resulting overload candidate set.

所以总是先找到在Int中声明的plus方法,搜索到此为止。您定义的任何扩展名都将被忽略。

假设, 如果 built-in Int.plus 是隐式导入的扩展函数,那么您的代码就可以工作!隐式导入的扩展在该列表中排名第 6 :)

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

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

fun main() {
    println( 1 `+` 2 )
}

这不适用于某些包含方括号、尖括号、斜线和点(并非详尽列表)等保留字符的名称。