如何(强制)在 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):
- Non-extension member callables named
f
of type T
;
- 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;
- [...]
[...]
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 )
}
这不适用于某些包含方括号、尖括号、斜线和点(并非详尽列表)等保留字符的名称。
我想让 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 receivere
of typeT
the following sets are analyzed (in the given order):
- Non-extension member callables named
f
of typeT
;- Extension callables named
f
, whose receiver typeU
conforms to typeT
, in the current scope and its upwards-linked scopes, ordered by the size of the scope (smallest first), excluding the package scope;- [...]
[...]
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 )
}
这不适用于某些包含方括号、尖括号、斜线和点(并非详尽列表)等保留字符的名称。