Now, it’s time to take your higher-order function skills to the next level. To code along, open Kotlin Playground from your browser. Let’s get going!
First, create an applyOperation() method that takes the two parameters of type Int, and a third parameter of a function type.
fun applyOperation(
num1: Int,
num2: Int,
operation: (Int, Int) -> Int): Int {
val startingTime = System.nanoTime()
val result = operation(num1, num2)
val endingTime = System.nanoTime()
val elapsedTime = endingTime - startingTime
println("Operation took $elapsedTime nanoseconds")
return result
}
applyOperations() is a higher-order function. It accepts another function, operation, as a parameter. The operation function returns an integer. applyOperation() first gets the current time and executes the function passed to it. Then gets the ending time, calculates the time it took for the operation to run and prints out the time. Last but not least it returns the result of applying the operation.
Next, create a lambda expression that takes two arguments of type Int and returns the product of the value passed.
val findProductLambda = { num1: Int, num2: Int -> num1 * num2 }
Now, call the applyOperation() method and pass the lambda you just created.
fun main() {
val numProduct = applyOperation(29, 30, findProductLambda)
println(numProduct)
}
When you run this code, it should print two things:
-
The amount of time it took to execute the
findProductLambdaexpression - The result of multiplying 29 and 30 - 870.
The time it takes to execute the findProductLambda expression will be different each time you run the example. For me, it looks like this:
Operation took 45685 nanoseconds
870
Trailing Lambdas
In Kotlin, if the last parameter of a function is itself a function, the lambda can be placed outside of the parentheses where the arguments normally go. This syntax is called trailing lambdas. Now, update the applyOperation() function call to use the trailing lambda syntax:
fun main() {
val numProduct = applyOperation(29, 30) { a, b ->
a * b
}
println(numProduct)
}
Note that you have to provide the names of the declared parameters, followed by an arrow -> symbol. Finally, you multiply the arguments passed. When you run the code, it prints the amount of time it took to run the operation and “870” just like before.
Suppose you just want to find the square of the first argument passed to the applyOperation() function. If you’re not using one of the parameters of a lambda, you can replace the name of the parameter with an underscore _. Next, update the applyOperation() function call to find the square of the first number.
fun main() {
val numSquare= applyOperation(29, 30) { a, _ ->
a * a
}
println(numSquare)
}
For the second argument, you used an underscore because the argument isn’t being used. When you run the code, the time it took to square 29 and the number “841” — the square of 29 — is printed on the screen.
The it Keyword
It’s very common for a lambda expression to have only one parameter. In those scenarios, Kotlin allows you to omit the name of the parameter and use the it keyword to refer to the parameter passed to the lambda. Create a method that sends a message and then logs the message sent.
fun sendMessage(message: String, logMessage: (String) -> Unit) {
logMessage(message)
println("Sending message....")
}
The logMessage lambda takes only one parameter - a String. Next, call the sendMessage() function using both the trailing lambda syntax and the new it keyword:
fun main() {
sendMessage(message = "Learning Kotlin") {
println(it)
}
}
This time, you didn’t have to pass the parameter’s name, and the arrow symbol — -> — was also omitted. The parameter was implicitly declared using the name it.
When you run the code, “Learning Kotlin” and then “Sending message….” is printed on the screen.
That ends this demo. Now, continue on for the lesson summary.