仍然无法将 Kotlin 泛型函数分配给 val?
Still impossible to assign Kotlin generic function to val?
在 Kotlin 中,我可以将函数分配给 val
。
fun intListCat(a: List<Int>, b: List<Int>): List<Int> = a.plus(b)
fun testIntListCat() {
val f = ::intListCat
println( f( listOf(1,2), listOf(30,40) ) )
}
但是当我使函数通用时,我无法将它分配给 val
。
fun<T> listCat(a: List<T>, b: List<T>): List<T> = a.plus(b)
fun testListCat() {
// error: Not enough information to infer type variable T.
val f1 = ::listCat
println( f1( listOf(1,2), listOf(30,40) ) )
// error: Unresolved reference T.
val f2: (List<T>, List<T>) -> List<T> = ::listCat
println( f2( listOf(1,2), listOf(30,40) ) )
}
令我惊讶的是,对一个简单函数的微小改动似乎使它失去了在 Kotlin 中作为高阶函数的资格,Kotlin 旨在尽可能地发挥功能。
两年多以前,有一个similar question on a Kotlin community support page。社区无法明确回答。而 Kotlin 团队没有回应。
我只是想知道从那时起 Kotlin 或程序员的知识是否有任何改变,以允许在 2022 年将通用函数分配给 val
?
我是 运行 Kotlin 1.6.20,在 macOS 11.3.1 上 Java 17.0.2。
不,这是不可能的。要让 val f1 = ::listCat
以您想要的方式工作,f1
也需要是通用的,但本地属性不能是通用的。
通过明确指定类型并将 T
替换为实际类型,您 可以 将 ::listCats
分配给本地 属性:
val f: (List<Int>, List<Int>) -> List<Int> = ::listCat
尽管现在您不能将其他类型的列表传递给 f
,这可能是不可取的。
另一方面,non-local属性可以是泛型的,但是它们的类型参数必须在接收者参数中使用,这意味着属性必须是一个扩展属性 ,因此这可能对您尝试做的任何事情都没有帮助。
在 Kotlin 中,我可以将函数分配给 val
。
fun intListCat(a: List<Int>, b: List<Int>): List<Int> = a.plus(b)
fun testIntListCat() {
val f = ::intListCat
println( f( listOf(1,2), listOf(30,40) ) )
}
但是当我使函数通用时,我无法将它分配给 val
。
fun<T> listCat(a: List<T>, b: List<T>): List<T> = a.plus(b)
fun testListCat() {
// error: Not enough information to infer type variable T.
val f1 = ::listCat
println( f1( listOf(1,2), listOf(30,40) ) )
// error: Unresolved reference T.
val f2: (List<T>, List<T>) -> List<T> = ::listCat
println( f2( listOf(1,2), listOf(30,40) ) )
}
令我惊讶的是,对一个简单函数的微小改动似乎使它失去了在 Kotlin 中作为高阶函数的资格,Kotlin 旨在尽可能地发挥功能。
两年多以前,有一个similar question on a Kotlin community support page。社区无法明确回答。而 Kotlin 团队没有回应。
我只是想知道从那时起 Kotlin 或程序员的知识是否有任何改变,以允许在 2022 年将通用函数分配给 val
?
我是 运行 Kotlin 1.6.20,在 macOS 11.3.1 上 Java 17.0.2。
不,这是不可能的。要让 val f1 = ::listCat
以您想要的方式工作,f1
也需要是通用的,但本地属性不能是通用的。
通过明确指定类型并将 T
替换为实际类型,您 可以 将 ::listCats
分配给本地 属性:
val f: (List<Int>, List<Int>) -> List<Int> = ::listCat
尽管现在您不能将其他类型的列表传递给 f
,这可能是不可取的。
另一方面,non-local属性可以是泛型的,但是它们的类型参数必须在接收者参数中使用,这意味着属性必须是一个扩展属性 ,因此这可能对您尝试做的任何事情都没有帮助。