如何避免返回SAM接口的函数的对象表达式

我是一个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) } } 

然后科特林说:

 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也将不胜感激。

由于没有类型别名(尚),类型签名不能*互相替代。 在你的情况下,你需要使用组合而不是继承来创建一个抽象层次:

 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) } }