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
就已经是一种美学上的折衷,但更容易接受),这有点难看,但它确实解决了这个问题。再次感谢!