Kotlin带接收者Lambda可调用外部函数?如何限制仅调用接收者方法?
Kotlin带接收者Lambda的作用域问题
为什么调用外部函数不会编译报错?
你定义的extension函数第二个参数是带接收者的Lambda类型(LambdaReceiver.() -> Unit),这种类型本质属于扩展函数类型。Kotlin的设计允许这类Lambda同时访问两个作用域:
- 接收者
LambdaReceiver的成员(比如setTest方法) - Lambda所在外部作用域的所有可访问元素(比如
main函数内定义的someOtherRandomFunction)
这是语言的正常特性,编译器不会将调用外部函数视为错误。
如何限制Lambda仅调用LambdaReceiver的相关方法?
要切断Lambda对外部作用域的访问,可通过接口隔离的方式,只暴露允许调用的方法:
- 定义仅包含允许调用方法的接口:
interface LambdaReceiverScope { fun setTest(int: Int) }
- 修改
LambdaReceiver实现该接口:
class LambdaReceiver(private val name: String) : LambdaReceiverScope { private var test: Int? = null override fun setTest(int: Int) { test = int println("$name $test") } }
- 更新
extension函数的参数类型为接口的扩展函数类型:
fun extension(name: String, init: LambdaReceiverScope.() -> Unit) { val lambdaReceiver = LambdaReceiver(name) lambdaReceiver.init() }
此时再调用extension时,Lambda内部只能访问LambdaReceiverScope中定义的方法,调用外部函数会直接编译报错:
fun main() { fun someOtherRandomFunction() { println("someOtherRandomFunction") } extension("testFunction") { someOtherRandomFunction() // 编译报错:Unresolved reference: someOtherRandomFunction setTest(1) } }
内容的提问来源于stack exchange,提问作者Suganthan Madhavan Pillai
相关产品推荐
相关产品推荐

