如何在有对象作用域的环境中调用非扩展 `运行` 函数(没有作用域的函数/"object reference")?
How can one invoke the non-extension `run` function (the one without scope / "object reference") in environments where there is an object scope?
示例:
data class T(val flag: Boolean) {
constructor(n: Int) : this(run {
// Some computation here...
<Boolean result>
})
}
在此示例中,自定义构造函数需要 运行 一些计算以确定将哪个值传递给主构造函数,但编译器不接受 run
,引用 Cannot access 'run' before superclass constructor has been called
,如果我理解正确的话,这意味着不是将其解释为非扩展 运行(在 https://kotlinlang.org/docs/reference/scope-functions.html#function-selection 中带有 no 对象引用的变体) ,它将其解释为对 this.run
的调用(变体 with 上面 table 中的对象引用)——这是无效的,因为对象尚未完全实例化还。
我该怎么做才能让编译器知道我指的是 run
函数,它不是扩展方法并且不采用范围?
澄清:我对问题的答案感兴趣,而不是解决方法。
我可以想到几种变通方法 - 以不调用 run
的方式按预期工作的方式重写此代码的方法:将代码提取到函数;将其重写为(可能高度嵌套的)let
表达式;删除 run
并调用 lambda(后面有 ()
)(有趣的是,IntelliJ IDEA 将其标记为 Redundant lambda creation
并建议 Inline the body
,这会恢复非编译 run
)。但问题是 而不是 如何在不使用 run
的情况下重写它 - 这是如何使 run
在这种情况下工作.
一个好的答案应该做以下事情之一:
- 解释一般情况下如何指示编译器在名称重载时调用函数而不是扩展方法;或
- 解释如何专门为
run
做到这一点;或
- 解释(最好还有为什么)这是不可能的(最好有支持性参考);或
- 解释我错了什么,以防我错了并且整个问题无关紧要(例如,如果我的分析不正确,并且问题出在编译器将对
run
的调用解释为this.run
).
如果有人有上面没有提到的巧妙解决方法,欢迎他们 post 在评论中提出 - 而不是作为答案。
以防万一:我使用的是多平台 Kotlin 1.4.20。
Kotlin 支持在范围内的接收器重载。解决方案是使用非接收函数的完全限定名称:
kotlin.run { //...
规格说明here.
当重载不在同一个包中时,另一种选择是使用 import renaming,但在这种情况下不起作用,因为两个 run
函数都在同一个包中。
示例:
data class T(val flag: Boolean) {
constructor(n: Int) : this(run {
// Some computation here...
<Boolean result>
})
}
在此示例中,自定义构造函数需要 运行 一些计算以确定将哪个值传递给主构造函数,但编译器不接受 run
,引用 Cannot access 'run' before superclass constructor has been called
,如果我理解正确的话,这意味着不是将其解释为非扩展 运行(在 https://kotlinlang.org/docs/reference/scope-functions.html#function-selection 中带有 no 对象引用的变体) ,它将其解释为对 this.run
的调用(变体 with 上面 table 中的对象引用)——这是无效的,因为对象尚未完全实例化还。
我该怎么做才能让编译器知道我指的是 run
函数,它不是扩展方法并且不采用范围?
澄清:我对问题的答案感兴趣,而不是解决方法。
我可以想到几种变通方法 - 以不调用 run
的方式按预期工作的方式重写此代码的方法:将代码提取到函数;将其重写为(可能高度嵌套的)let
表达式;删除 run
并调用 lambda(后面有 ()
)(有趣的是,IntelliJ IDEA 将其标记为 Redundant lambda creation
并建议 Inline the body
,这会恢复非编译 run
)。但问题是 而不是 如何在不使用 run
的情况下重写它 - 这是如何使 run
在这种情况下工作.
一个好的答案应该做以下事情之一:
- 解释一般情况下如何指示编译器在名称重载时调用函数而不是扩展方法;或
- 解释如何专门为
run
做到这一点;或 - 解释(最好还有为什么)这是不可能的(最好有支持性参考);或
- 解释我错了什么,以防我错了并且整个问题无关紧要(例如,如果我的分析不正确,并且问题出在编译器将对
run
的调用解释为this.run
).
如果有人有上面没有提到的巧妙解决方法,欢迎他们 post 在评论中提出 - 而不是作为答案。
以防万一:我使用的是多平台 Kotlin 1.4.20。
Kotlin 支持在范围内的接收器重载。解决方案是使用非接收函数的完全限定名称:
kotlin.run { //...
规格说明here.
当重载不在同一个包中时,另一种选择是使用 import renaming,但在这种情况下不起作用,因为两个 run
函数都在同一个包中。