如何避免 return SAM 接口的函数的对象表达式
How do I avoid object expressions for functions that return a SAM interface
我是 kotlin 新手,所以这可能是微不足道的,但我未能在 kotlinlang.org 找到任何相关帮助。
为了学习一些关于 kotlin 的知识,我喜欢实现 PushStream
库。
我想像这样定义基本类型:
typealias Receiver<T> = (T) -> bool
typealias PushStream<T> = (Receiver<T>) -> Unit
尚不支持 AFAIK 类型别名,因此以上只是伪代码。
所以我的第一次尝试是这样的:
interface Receiver<T> : (T) -> Boolean {
}
interface PushStream<T> : (Receiver<T>) -> Unit {
}
fun <T> singleton (v : T) : PushStream<T> {
return { r : Receiver<T> -> r (v) }
}
kotlin 然后说:
Error:(10, 12) Kotlin: Type mismatch: inferred type is (Receiver<T>) -> Boolean but PushStream<T> was expected
我似乎可以通过以下方式绕过它:
fun <T> singleton (v : T) : (Receiver<T>) -> Unit {
return { r : Receiver<T> -> r (v) }
}
但这不是我想要的签名,特别是对于更高级的运算符,我可能需要指定完整的函数类型:
fun <T> singleton (v : T) : ((T) -> Boolean) -> Unit {
return { r : Receiver<T> -> r (v) }
}
我认为这会使 API 更难阅读。
我能做的是使用对象表达式:
fun <T> singleton (v : T) : PushStream<T> {
return object : PushStream<T> {
operator override fun invoke (r : Receiver<T>) : Unit {
r (v)
}
}
}
这可行,但我想使用 Lambda 表达式使代码更简洁。
欢迎任何提示。此外,如果您知道任何关于在 kotlin 中使用高阶函数进行编程的有趣 blogs/presentations,我们也将不胜感激。
由于(还)没有类型别名,类型签名不能*相互替代。在您的情况下,您需要使用组合而不是继承来创建抽象级别:
open class Receiver<T>(val op: (T) -> Boolean)
open class PushStream<T>(val op: (Receiver<T>) -> Unit)
fun <T> singleton (v: T): PushStream<T> {
return PushStream<T> { r -> r.op(v) }
}
我用 类 替换了接口,因为我看不到其余代码。如果你需要接口,那么使用工厂函数:
interface Receiver<T> {
val op: (T) -> Boolean
}
fun <T> receiver(op: (T) -> Boolean) = object : Receiver<T> {
override val op = op
}
如果您在 java 中定义了 PushStream 接口,您可以像这样使用它:
fun <T> singleton (v : T) : PushStream<T> {
return PushStream { r : Receiver<T> -> r (v) }
}
我是 kotlin 新手,所以这可能是微不足道的,但我未能在 kotlinlang.org 找到任何相关帮助。
为了学习一些关于 kotlin 的知识,我喜欢实现 PushStream
库。
我想像这样定义基本类型:
typealias Receiver<T> = (T) -> bool
typealias PushStream<T> = (Receiver<T>) -> Unit
尚不支持 AFAIK 类型别名,因此以上只是伪代码。
所以我的第一次尝试是这样的:
interface Receiver<T> : (T) -> Boolean {
}
interface PushStream<T> : (Receiver<T>) -> Unit {
}
fun <T> singleton (v : T) : PushStream<T> {
return { r : Receiver<T> -> r (v) }
}
kotlin 然后说:
Error:(10, 12) Kotlin: Type mismatch: inferred type is (Receiver<T>) -> Boolean but PushStream<T> was expected
我似乎可以通过以下方式绕过它:
fun <T> singleton (v : T) : (Receiver<T>) -> Unit {
return { r : Receiver<T> -> r (v) }
}
但这不是我想要的签名,特别是对于更高级的运算符,我可能需要指定完整的函数类型:
fun <T> singleton (v : T) : ((T) -> Boolean) -> Unit {
return { r : Receiver<T> -> r (v) }
}
我认为这会使 API 更难阅读。
我能做的是使用对象表达式:
fun <T> singleton (v : T) : PushStream<T> {
return object : PushStream<T> {
operator override fun invoke (r : Receiver<T>) : Unit {
r (v)
}
}
}
这可行,但我想使用 Lambda 表达式使代码更简洁。
欢迎任何提示。此外,如果您知道任何关于在 kotlin 中使用高阶函数进行编程的有趣 blogs/presentations,我们也将不胜感激。
由于(还)没有类型别名,类型签名不能*相互替代。在您的情况下,您需要使用组合而不是继承来创建抽象级别:
open class Receiver<T>(val op: (T) -> Boolean)
open class PushStream<T>(val op: (Receiver<T>) -> Unit)
fun <T> singleton (v: T): PushStream<T> {
return PushStream<T> { r -> r.op(v) }
}
我用 类 替换了接口,因为我看不到其余代码。如果你需要接口,那么使用工厂函数:
interface Receiver<T> {
val op: (T) -> Boolean
}
fun <T> receiver(op: (T) -> Boolean) = object : Receiver<T> {
override val op = op
}
如果您在 java 中定义了 PushStream 接口,您可以像这样使用它:
fun <T> singleton (v : T) : PushStream<T> {
return PushStream { r : Receiver<T> -> r (v) }
}