Kotlin伴生对象中调用带接收者函数报错问题咨询
问题解答
带接收者函数不存在“仅能在特定作用域使用”的特殊限制,它的作用域规则和普通函数、普通Lambda完全一致,你代码里调用报错,本质是作用域访问权限问题,和带接收者函数本身的特性无关。
报错原因
你定义的multiplyBy是KotlinReceiverFunction类的实例成员属性,访问它必须依赖KotlinReceiverFunction的类实例;而伴生对象的成员是和类本身绑定的,不需要类实例就能访问,伴生对象的默认作用域里根本没有multiplyBy这个属性,自然没法直接调用。
这里补个关键规则:定义在类内部的成员扩展(也就是你写的这种带接收者函数)有两类接收者:
- 扩展接收者:扩展函数的接收类型,这里是
Int,也就是调用时.前面的整型对象 - 分发接收者:定义这个扩展的外部类实例,这里是
KotlinReceiverFunction的实例
你之前的调用场景里,缺了分发接收者的作用域上下文,所以直接报编译错误。
可行实现方案
根据你的使用场景,选下面任意一种都能实现伴生对象内的正常调用:
方案1:把带接收者函数挪到伴生对象内部
如果这个函数只需要在伴生对象、类内部逻辑里用,直接把属性挪到伴生对象里就行,伴生对象内部可以直接访问自身的成员属性:
class KotlinReceiverFunction { companion object { // 扩展属性放到伴生对象作用域内 private val multiplyBy = fun Int.(value: Int) = this * value fun printMultiplicationResult(a: Int, b: Int) = a.multiplyBy(b) } }
方案2:显式传入外部类实例,带入分发接收者作用域
如果你必须把multiplyBy作为外部类的实例成员保留,调用的时候显式传入外部类实例,用with函数把分发接收者的作用域带进去就行:
class KotlinReceiverFunction { val multiplyBy = fun Int.(value: Int) = this * value companion object { // 传入外部类实例作为分发接收者 fun printMultiplicationResult(a: Int, b: Int, outerInstance: KotlinReceiverFunction): Int { return with(outerInstance) { // 当前作用域存在multiplyBy成员,可以正常调用 a.multiplyBy(b) } } } }
方案3:定义为顶层属性全局访问
如果这个带接收者函数需要在多个类、多个场景通用,直接把它定义成顶层属性(不要放在任何类内部),所有作用域都能直接访问,不需要额外处理上下文。
内容的提问来源于stack exchange,提问作者ha9u63a7
相关产品推荐
相关产品推荐

