如何在kotlin中编写含泛型的lambdas?
我可以使用显式类型编写lambdas id_Int
和id_Boolean
。 我可以用类型参数编写函数identity
。 我可以用类型参数写lambda吗?
fun testFuncInt(f: (Int) -> Int): Int = f(1) + 2 val id_Int = { x: Int -> x } fun testFuncBoolean(f: (Boolean) -> Boolean): Boolean = !f(false) val id_Boolean = { x: Boolean -> x } fun <T> identity(x: T) = x fun main(args: Array<String>) { println(testFuncInt(id_Int)) println(testFuncInt(::identity)) println(testFuncBoolean(id_Boolean)) println(testFuncBoolean(::identity)) }
Kotlin不支持声明泛型属性而不声明类级别的类型( 另请参见 ),但是可以使用返回与所需类型相对应的lambda的函数来实现:
fun main(args: Array<String>) { println(testFuncBoolean(id())) println(testFuncInt(id())) } fun <T> id(): (T) -> T = { it } fun testFuncInt(f: (Int) -> Int): Int = f(1) + 2 fun testFuncBoolean(f: (Boolean) -> Boolean): Boolean = !f(false)
不,但你通常不需要。 一个lambda没有声明(这是点的),所以它本质上是一个表达式,你可以传递给一个函数,存储在一个val
/ var
就像你做val id_Boolean = { x: Boolean -> x }
类型真的得到了解决,因为它会在表达式中。
这里的调用将解析为正确的类型,因为你的函数接受一个函数,该函数接受一个Int
并返回一个Int
,一个函数接受一个Boolean
并返回一个Boolean
testFuncInt({ x -> x }) // x is an Int testFuncInt({ it }) // it is the default argument testFuncInt { x -> x } // as top one, Kotlin's syntactic sugar
这里最重要的是lambda表达式仍然提供类型安全性,即如果你做了这样的事情
fun <T> foo(x: T, lambda: (T) -> Boolean): Boolean = lambda(x) foo(42, { x -> x }) // oops, lambda takes a T and returns a T
这会引发编译器错误,因为lambda
的类型与foo
期望的不匹配,即foo
会将Int
传递给lambda,并且期望返回Boolean
。 另一方面,如果你这样做
foo(123, { it == 42 }) foo(123) { it == 42 } // equivalent to above
返回类型实际上被推断为Boolean
因为这是比较操作的结果,因为123和42是相同的类型, lambda
的类型实际上符合foo
期望。
你不能用泛型来写lambda, 为什么从正式文档中取下的段落说明了这一切。
一个lambda表达式或一个匿名函数是一个“函数文字”,即一个没有声明的函数,但是立即作为一个表达式来传递
lambda表达式或函数没有声明,它是一个匿名函数。
但最终我们通过将函数类型声明为泛型来做同样的事情。 我们可以传递一个lambda表达式来完成这个工作。
fun testFuncInt(f: (Int) -> Int): Int = f(1) + 2
你可以这样调用它: testFuncInt{ a -> a }
或testFuncInt{ it }
所以最后你做同样的事情(带有类型参数的lambdas),但没有像这样的术语,因为lambdas是表达式或匿名函数。
希望它有帮助。