generics - Kotlin 中的通用 lambda 或函数值类型

标签 generics types functional-programming kotlin

给定一个函数

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

是否可以将其分配给变量(值)funVal像这样 ?
val funVal: (T) -> Int = ::to5

没有

Unresolved reference: T



错误 ?

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

例如像这样:
val <T> funVal: (T) -> Int = ::to5

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

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

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

用例

我的用例是使用泛型的柯里化(Currying)。从概念上讲:
    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>

我能想到的解决方案是:

包裹在通用乐趣中 (基本上不是真正的柯里化(Currying)或高阶函数使用)
 fun <T> pairAnyWithAbc(t: T) {
        return pairAnyWithAbc(t)
 }

为每种类型创建函数 (不使用泛型,因为我想)
val pairStrWithAbc: (String) -> Pair<String, String> = pairStrWithAny("abc")

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

最佳答案

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

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

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

关于generics - Kotlin 中的通用 lambda 或函数值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48487689/

相关文章:

f# - 如何在 F# 中声明返回满足多个约束的类型的泛型函数?

java - 为什么 Java 通配符比 use-site variance 更强大?

java - 返回类型中的推断通配符泛型

java - 为什么我不能扩展接口(interface) "generic method"并将其类型缩小到继承的接口(interface) "class generic"?

javascript - 哪种风格更适合 checkin JavaScript?

ios - 单例中的@Published 属性在第一个事件之后不发出事件

types - 在 BigQuery 中指定字符串列长度有什么理由或优势吗?

c++ - 迭代器类型中使用的 vector 元素类型

.net - F# 中的函数应用运算符 ($)?

具有输出列表长度的 Haskell 排列