Reputation: 499
I am novice to functional programming in java/kotlin and do some practice. Just wonder how can I pass parameters of lambda when invoking it. For example, here to call someMethod I need to pass an Int parameter.
fun lambdaTest( someMethod: (Int) -> Boolean){
someMethod()
}
How that can be done? The answer may be very simple, I just didn't find it anywhere, in the documentation there were only examples with lists, in case of which the answer is clear:
fun <T, R> List<T>.map(transform: (T) -> R): List<R> {
val result = arrayListOf<R>()
for (item in this)
result.add(transform(item))
return result
}
Upvotes: 1
Views: 1535
Reputation: 1257
Think of (Int) -> Boolean
as being equivalent to the following interface (in fact, that's actually what is compiled on the JVM) :
interface Function<I, O> {
fun inkoke(param: I): O
}
I
is the type of the input parameter, O
is the type of the output type (returned value).
All lambda in Kotlin are in fact a shorthand syntax for defining an object with a single method invoke
with a given number of parameters and a return type.
Let's rewrite your high-order function taking this into account.
fun lambdaTest(someMethod: Function<Int, Boolean>) {
// Call invoke with an Int paramater. This returns a Boolean.
val isTheAnswerOfTheUniverse = someMethod.invoke(42)
}
Now, we call this method :
// We can pass an anonymous class as the parameter
lambdaTest(object : Function<Int, Boolean>() {
override fun invoke(param: Int): Boolean {
println("Lambda called with number: $param")
// Prints "Lambda called with number: 42"
return param == 42
}
})
This is the same with (Int) -> Boolean
. The only difference is syntax: as Kotlin is also a functional language, it offers syntactic sugar to improve readability and reduce boilerplate, such as
.invoke
can be omitted (because it is an operator overload)Here is the equivalent with lambda syntax:
fun lambdaTest(someMethod: (Int) -> Boolean) {
val isTheAnswerOfTheUniverse = someMethod(42)
}
fun main(args: Array<String>) {
lambdaTest { param ->
println("Lambda called with number: $param")
// Prints "Lambda called with number: 42"
// The result of the last expression is returned
param == 42
}
}
Upvotes: 2
Reputation: 1815
Here you need to pass function that takes Int as argument and returns Boolean.
lambdaTest { int ->
int > 0 // can be also changed to it
}
Here we return true if Int parameter is more than 0.
If you want more parameters:
fun lambdaTest( someMethod: (Int, String) -> Unit){ // Unit means do not return anything
someMethod(1, "Kotlin")
}
And call it:
lambdaTest { int, string ->
println("Passed Int: $int, and String: $string as parameter")
// Output = Passed Int: 1, and String: Kotlin as parameter
}
Upvotes: 2