如何在 Kotlin 中将函数接收器类型与 SAM 接口一起使用
Posted
技术标签:
【中文标题】如何在 Kotlin 中将函数接收器类型与 SAM 接口一起使用【英文标题】:How to use function receiver type with SAM interfaces in Kotlin 【发布时间】:2022-01-08 21:56:16 【问题描述】:我来自 Java,并且是 Kotlin 的新手。我试图了解如何将receiver type 与指定为功能SAM interfaces 的lambda 一起使用。
让代码自己说话。
fun interface Delegator <T>
fun delegate(receiver: T)
fun <T> invokeWithDynamicReceiver(receiver: T, fn: T.() -> Unit) = receiver.fn()
fun <T> invokeWithSamInterface(receiver: T, fn: Delegator<T>) = fn.delegate(receiver)
fun dynamicReceiver()
invokeWithDynamicReceiver("Foo") length // Dynamic receiver
invokeWithSamInterface("Foo") it.length // Can't bind receiver as "this"
如何更改代码以将Delegator
lambda 与动态接收器一起使用?
【问题讨论】:
【参考方案1】:您可以将Delegator
中的函数定义为扩展函数,这样接收者将作为this
传递给lambda。
fun interface ExtensionDelegator <T, R>
fun T.delegate(): R
fun <T, R> invokeWithExtensionSamInterface(receiver: T, fn: ExtensionDelegator<T, R>): R =
with(fn) receiver.delegate()
或者,您可以简单地使用typealias
定义动态接收器以实现相同的结果。
typealias AliasDelegator<T, R> = T.() -> R
fun <T, R> invokeWithAliasSamInterface(receiver: T, fn: AliasDelegator<T, R>): R = fn.invoke(receiver)
在使用网站上,这两种方法看起来是一样的。
fun main()
val result = invokeWithExtensionSamInterface("Foo") length
println(result)
val otherResult = invokeWithAliasSamInterface("Fizz") length
println(otherResult)
【讨论】:
以上是关于如何在 Kotlin 中将函数接收器类型与 SAM 接口一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 RxJava 2 和 Kotlin 中将 null 传递给具有可空类型的 Observable