通过lambda的返回类型区分具有lambda参数的函数?

时间:2020-10-30 09:36:29

标签: kotlin

我有一个函数timeout(...)(扩展函数返回this),该函数接受一个StringDateLong的参数。我想做的是使它接受也返回这三种类型之一的任何lambda。

Kotlin发现以下函数是模棱两可的,并且在我键入timeout { "something" }时无法确定要调用哪个函数。

@JvmName("timeoutString")
fun <CR: CachableResponse> CR.timeout(timeLambda: CR.()->String): CR = timeout(timeLambda())

@JvmName("timeoutLong")
fun <CR: CachableResponse> CR.timeout(timeLambda: CR.()->Long): CR = timeout(timeLambda())

@JvmName("timeoutDate")
fun <CR: CachableResponse> CR.timeout(timeLambda: CR.()->Date): CR = timeout(timeLambda())

我遇到的错误是Cannot choose among the following candidates without completing type inference

当然,解决此问题的一种方法是拥有一个功能,而不是像这样的三个功能:

fun <CR: CachableResponse, Type> CR.timeout(timeLambda: CR.()->Type): CR =
        timeLambda().let { when (it) {
            is String -> timeout(it)
            is Date -> timeout(it)
            is Long -> timeout(it)
            else -> this
        } }

但是,在这种情况下,如果不阅读说明或检查源代码,开发人员将不知道其lambda将返回什么。

还有更优雅的解决方案吗?

1 个答案:

答案 0 :(得分:1)

实际上,您的解决方案相当优雅。 我只建议内联CR通用参数,并在变量中捕获when主题:

fun <Type> CachableResponse.timeout(timeLambda: CachableResponse.() -> Type) =
    when (val it = timeLambda()) {
        is String -> timeout(it)
        is Date -> timeout(it)
        is Long -> timeout(it)
        else -> this
    }

但是,在这种情况下,如果不阅读说明或检查源代码,开发人员将不知道其lambda将返回什么。

IDE来了:

enter image description here enter image description here