Kotlin 在有对象作用域的环境中,如何调用非扩展“run”函数(没有作用域的函数/“object reference”)?
例如:Kotlin 在有对象作用域的环境中,如何调用非扩展“run”函数(没有作用域的函数/“object reference”)?,kotlin,extension-methods,overload-resolution,Kotlin,Extension Methods,Overload Resolution,例如: data class T(val flag: Boolean) { constructor(n: Int) : this(run { // Some computation here... <Boolean result> }) } 数据类T(val标志:布尔值){ 构造函数(n:Int):这个(run){ //这里有一些计算。。。 }) } 在本例中,自定义构造函数需要运行一些计算以确定要传递给主构造函数的值,但编译器不接
data class T(val flag: Boolean) {
constructor(n: Int) : this(run {
// Some computation here...
<Boolean result>
})
}
数据类T(val标志:布尔值){
构造函数(n:Int):这个(run){
//这里有一些计算。。。
})
}
在本例中,自定义构造函数需要运行一些计算以确定要传递给主构造函数的值,但编译器不接受run
,引用无法在调用超类构造函数之前访问“run”,如果我理解正确,表示不将其解释为非扩展运行(中没有对象引用的变量),而是将其解释为对this.run
(上表中有对象引用的变量)的调用,这是无效的,因为对象尚未完全实例化
我该怎么做才能让编译器知道我指的是run
函数,它不是一个扩展方法,也没有作用域
澄清:我感兴趣的是问题的答案,而不是解决方法。
我可以想出几种变通方法——以一种不调用run
的方式重写代码:将代码提取到函数中;将其重写为(可能高度嵌套的)let
表达式;删除运行
并调用lambda(后面带有()
)(有趣的是,IntelliJ IDEA将其标记为冗余lambda创建
,并建议内联主体
,从而恢复非编译的运行
)。但是问题是不是如何在不使用run
的情况下重写它-问题是如何使run
在这种情况下工作
一个好的答案应该做以下事情之一:
- 解释当名称重载时,通常如何指示编译器调用函数而不是扩展方法;或
- 解释如何专门为
运行执行此操作;或
- 解释(理想情况下也是为什么)不可能做到(理想情况下有支持性参考);或
- 解释我做错了什么,以防我做错了什么,而整个问题都无关紧要(例如,如果我的分析不正确,并且问题不是编译器将调用
run
解释为this.run
)
如果有人有一个整洁的解决方法,上面没有提到,他们欢迎张贴在评论-而不是作为一个答案
如果重要的话:我使用的是多平台Kotlin 1.4.20。如果接收器过载在范围内,Kotlin会支持它。解决方案是使用非接收方函数的完全限定名称:
kotlin.run { //...
对规范进行了解释
当重载不在同一个包中时,另一个选项是使用,但在这种情况下,这不起作用,因为两个run
函数都在同一个包中。只需使用完全限定的kotlin.run{}
?谢谢,@gidds。我不确定你评论末尾的问号是什么意思,但如果这是一个问题,那么答案可能是我不知道有一个kotlin
包,我认为一些内置的东西——比如运行
函数——实际上只是该包的普通成员。现在一切都好了,谢谢!我不确定这样一个简单的答案是否符合您的严格标准:-),但Kotlin就像Java:您可以始终通过其完全限定名(即在包层次结构中的位置)引用任何类。 标准库(run()函数来自该库)也不例外。 如果您不确定,您的IDE将能够告诉您函数的来源。谢谢,@Tenfour04!如何调用东西的规范是明确的——我不清楚的是,“内置的”run
函数只是一个名为kotlin
的包的普通成员,我不知道它的存在。顺便说一句,我觉得写kotlin,run
(光是run
就已经是一种美学上的折衷,但更容易接受),这有点难看,但它确实解决了这个问题。再次感谢!