Kotlin文档指出“功能是一流的”。我正在尝试使用函数作为函数扩展的默认值。但是,编译器没有任何内容:
fun <T> identity(x: T): T = x
fun <T, P> Channel<T>.dedupe(by: (T) -> P = ::identity): ReceiveChannel<T>
{
...
}
错误是Function invocation 'identity(...)' expected
,有点说明Kotlin根本不了解我想做什么。
有办法吗?
答案 0 :(得分:2)
我不知道为什么会收到此错误消息,但是问题是类型不匹配:默认值必须对任何类型参数都有意义(受边界限制)。即您需要一个(T) -> P
,但是::identity
可以给您(T) -> T
或(P) -> P
。
证明:如果更改为
fun <T, P> identity(x: T): P = throw Exception()
fun <T, P> List<T>.dedupe(by: (T) -> P = ::identity): Unit {}
它会编译。
如果将P
更改为Any?
,我们应该可以使用::identity
,因为(T) -> T
是(T) -> Any?
的子类型。不幸的是,它不起作用,但是使用lambda代替函数引用可以做到:
fun <T> identity(x: T): T = x
fun <T> Channel<T>.dedupe(by: (T) -> Any? = { it }): ReceiveChannel<T>
{
...
}