如何在 Kotlin 中使用带有 SAM 接口的函数接收器类型
How to use function receiver type with SAM interfaces in Kotlin
我来自 Java,是 Kotlin 的新手。我试图了解如何使用 receiver type with lambdas specified as functional SAM interfaces.
让代码自己说话。
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 与动态接收器一起使用?
您可以将 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)
}
我来自 Java,是 Kotlin 的新手。我试图了解如何使用 receiver type with lambdas specified as functional SAM interfaces.
让代码自己说话。
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 与动态接收器一起使用?
您可以将 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)
}