【问题标题】:Generic lambda or function value type in KotlinKotlin 中的通用 lambda 或函数值类型
【发布时间】:2018-07-07 08:20:22
【问题描述】:

给定一个函数

fun <T> to5(x: T): Int = 5

是否可以像这样将其分配给变量(值)funVal

val funVal: (T) -> Int = ::to5

没有

未解决的参考:T

错误?

换句话说,是否有可能以某种方式告诉 Kotlin funVal 类型声明中的 T 是类型参数?

例如这样:

val <T> funVal: (T) -> Int = ::to5

val funVal<T>: (T) -> Int = ::to5

val funVal: <T> (T) -> Int = ::to5

val funVal: ((T) -> Int) <T> = ::to5

用例

我的用例是使用泛型的柯里化。从概念上讲:

    fun pairStrWithStr(s: String): (String) -> Pair<String, String> = {
        Pair(s, it)
    }

    val pairStrWithAbc: (String) -> Pair<String, String> = pairStrWithStr("abc")

    pairStrWithAbc("xyz") // (abc, xyz)

使第二个参数泛型:

fun <T> pairStrWithAny(s: String): (T) -> Pair<String, T> = {
    Pair(s, it)
}

// Compilation ERROR: Unresolved reference: T
val pairAnyWithAbc: (T) -> Pair<String, T> = pairStrWithAny("abc")

当然我可以提供Any 作为类型:

val pairAnyWithAbc: (Any) -> Pair<String, Any> = pairStrWithAny("abc")

但后来我丢失了类型信息:

pairAnyWithAbc(5) // Pair<String, Any>

我能想到的解决办法是:

包装在泛型 fun 中(基本上不是真正的柯里化或高阶函数用法)

 fun <T> pairAnyWithAbc(t: T) {
        return pairAnyWithAbc(t)
 }

为每种类型创建函数(我不想使用泛型)

val pairStrWithAbc: (String) -> Pair<String, String> = pairStrWithAny("abc")

val pairIntWithAbc: (Int) -> Pair<String, Int> = pairStrWithAny("abc")

【问题讨论】:

  • 你的用例是什么?
  • @s1m0nw1 我添加了用例

标签: generics types functional-programming kotlin


【解决方案1】:

在 Kotlin 中,只有类和函数可以具有泛型类型参数。如果你真的需要一个属性来拥有一个泛型类型,它必须属于可以提供该泛型类型的类实例,如下所示:

class Foo<T> {
    val funVal: (T) -> Int = ::to5
}

关于此here 的讨论更多,我只是无法将其标记为重复,因为该问题没有可接受的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多