求助:Kotlin带接收者函数类型两种调用方式的原理解析
Kotlin带接收者函数类型的两种调用方式解析
先看你定义的这个带接收者的函数:
val foo: Int.() -> Int = { plus(1) // 等价于 this.plus(1),this就是Int类型的接收者 }
这里的Int.() -> Int是带接收者的函数类型,它表示这个函数必须依附于一个Int类型的对象(也就是接收者)才能执行,函数内部可以直接访问接收者的成员方法和属性。
两种调用方式的本质
成员式调用:
1.foo()
这是最直观的用法,把1作为接收者,像调用Int的扩展函数一样调用foo,和你写一个扩展函数fun Int.foo() = plus(1)后调用1.foo()完全一致。参数式调用:
foo(1)
Kotlin编译器对带接收者的函数类型做了特殊处理:它会自动把带接收者的函数类型兼容成「以接收者为第一个参数」的普通函数类型。也就是说,Int.() -> Int可以被当作(Int) -> Int来使用。
当你调用foo(1)时,编译器会自动把1作为接收者传递给foo函数,等价于1.foo(),内部逻辑完全一样。
为什么要支持这种写法?
这种设计是为了兼顾灵活性:
- 在DSL场景中,成员式调用
1.foo()能让代码更贴近自然语言,可读性更高; - 而参数式调用
foo(1)则方便在需要传递普通函数类型的上下文里使用,比如把foo传给一个接收(Int) -> Int类型参数的高阶函数时,不需要额外转换。
内容的提问来源于stack exchange,提问作者ctapp1
相关产品推荐
相关产品推荐

