Kotlin中如何将扩展方法绑定到接收者作用域函数中使用?
Kotlin接口内扩展函数调用问题解决办法
问题原因
你在接口Example内定义的interfaceRunInTest()是带分发接收者的成员扩展函数,它同时关联两个接收者:
- 扩展接收者:
TestClass的实例(函数内部this指向的对象) - 分发接收者:
Example的实例(访问name属性的来源)
全局扩展函数standaloneRunInTest()仅绑定TestClass作为扩展接收者,因此在testScope的TestClass作用域内可直接调用。但成员扩展函数必须同时提供两个接收者才能正常执行,你原有的调用方式既没关联TestClass实例,也不符合成员扩展函数的调用语法,因此触发"Unresolved reference"错误。
解决办法
方法1:用作用域函数绑定分发接收者
在testScope的TestClass作用域内,通过with或run绑定Example.Instance作为分发接收者,此时扩展接收者默认是外部的TestClass实例:
fun main() { testScope { standaloneRunInTest() // prints "bar" // 正确调用,输出"barBaz" with(Example.Instance) { interfaceRunInTest() } } }
方法2:显式指定两个接收者
通过作用域函数或直接调用的方式,同时明确传递Example实例和TestClass实例:
fun main() { testScope { standaloneRunInTest() // prints "bar" // 显式指定两个接收者的写法 Example.Instance.run { this@TestScope.interfaceRunInTest() } // 更直白的等价写法 this.interfaceRunInTest(Example.Instance) } }
方法3:重构为普通成员函数(可选)
如果不需要严格使用扩展函数形式,可将逻辑改为Example的普通成员函数,接收TestClass实例作为参数:
interface Example { val name: String fun interfaceRunInTest(testClass: TestClass) { println(testClass.foo + name) } object Instance: Example { override val name: String = "Baz" } } // 调用方式 fun main() { testScope { standaloneRunInTest() // prints "bar" Example.Instance.interfaceRunInTest(this) // 输出"barBaz" } }
内容的提问来源于stack exchange,提问作者Zak Henry
相关产品推荐
相关产品推荐

