Recently, I’ve noticed that there are a few different ways to pass a function as parameter in Kotlin. In this post I will use 2 functions: sum
and divide
. We have to declare the sum
function, in such way that it can receive the divide
function as argument.
The most common and often more convenient (according to Kotlin documentation) is to pass a lambda expression.
1. Pass a lambda expression
In order to make the sum
function to accept a function passed as lambda expression, we have to declare the 3rd parameter c
as a lambda.
lambda expression with no parameters
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sum = sum(6, 3, { divide(6, 3) }) // returns 11
Log.e("SUM", sum.toString())
}
private fun sum(a: Int, b: Int, c: () -> Int): Int {
return a + b + c()
}
private fun divide(a: Int, b: Int): Int {
return a / b
}
}
lambda expression with 2 parameters
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sum = sum(6, 3, { a, b -> divide(a, b) }) // returns 11
Log.e("SUM", sum.toString())
}
private fun sum(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return a + b + c(a, b)
}
private fun divide(a: Int, b: Int): Int {
return a / b
}
}
pass lambda expression directly without divide
method
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sum = sum(6, 3, { a, b -> a / b }) // returns 11
Log.e("SUM", sum.toString())
}
private fun sum(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return a + b + c(a, b)
}
}
2. Use ::
operator
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sum = sum(6, 3, (this::divide)(6,3))// returns 11
Log.e("SUM", sum.toString())
}
private fun sum(a: Int, b: Int, c: Int): Int {
return a + b + c
}
private fun divide(a: Int, b: Int): Int {
return a / b
}
}
As you can see, the signature for the 3rd param from sum
function also changed. As we do not pass a function as lambda, we declare the c
parameter as a “normal” Int.
Also, notice how we had to reference the divide
function in this case. We had to specify the context (the class in which the function was declared), and the arguments were declared separately inside other parenthesis.
(this::divide)(6,3)
Specifying the context was necessary because the functions are declared in a class. Only if we write the functions directly in a Kotlin file (NOT inside a class) we can call directly ::divide.
See the example below: