函数可以是默认参数值吗?

时间:2018-07-05 12:01:14

标签: kotlin

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根本不了解我想做什么。

有办法吗?

1 个答案:

答案 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>
{
    ...
}