I can write lambdas id_Int
and id_Boolean
with explicit type. And I can write function identity
with type parameter. Can I write lambdas with type parameter?
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 generic extension function example As extension function allows to add methods to class without inherit a class or any design pattern. In this example, we add a method printValue()to ArrayList class of generic type. This method is called form stringList. printValue() and floatList.
Unit in Kotlin corresponds to the void in Java. Like void, Unit is the return type of any function that does not return any meaningful value, and it is optional to mention the Unit as the return type. But unlike void, Unit is a real class (Singleton) with only one instance.
How can I idiomatically achieve this in Kotlin? You need to pass a KClass<out Cell> as a constructor parameter to CellList , and to invoke the constructor using reflection. You can also create a factory function with a reified type parameter to enable creating CellList instances with a somewhat cleaner syntax.
Kotlin does not have support for declaring generic properties without declaring that type at class level (see also), but you can do it using a function that returns a lambda corresponding to the desired type:
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)
You can not write lambda with generics, why following paragraph taken from official documentation says it all.
A lambda expression or an anonymous function is a "function literal", i.e. a function that is not declared, but passed immediately as an expression
A lambda expression or function is not declared, its an anonymous function.
But ultimately we do same thing by declaring function type as generic. We can pass a lambda expression that does the job.
fun testFuncInt(f: (Int) -> Int): Int = f(1) + 2
you can call it like: testFuncInt{ a -> a }
or testFuncInt{ it }
So finally you are doing same thing (lambdas with type parameter), but there is no term like that as lambdas are expressions or anonymous functions.
Hope it helps.
No, but you generally don't need to. A lambda has no declaration (which is kind of the point), so it's essentially an expression you can pass to a function, store in a val
/var
as you did when doing
val id_Boolean = { x: Boolean -> x }
but the type really gets worked out as it would in an expression.
The calls here will resolve to the correct type, since your functions takes a function that takes an Int
and returns an Int
, and a function that takes a Boolean
and returns a 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
The important thing here is that the lambda expression still offers type safety, i.e. if you did something like this
fun <T> foo(x: T, lambda: (T) -> Boolean): Boolean = lambda(x)
foo(42, { x -> x }) // oops, lambda takes a T and returns a T
this will trigger a compiler error as lambda
's types don't match what foo
expects, i.e. foo
will pass an Int
to the lambda and it expects a Boolean
back. On the other hand, if you do this
foo(123, { it == 42 })
foo(123) { it == 42 } // equivalent to above
The return type is actually deduced to be a Boolean
as that's what the result of a comparison operation evaluates to and as 123 and 42 are of the same type, lambda
's types actually fit into what foo
expects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With