Kotlin: how to pass a function as parameter to another?

Kotlin

Kotlin Problem Overview


Given function foo :

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}

We can do:

foo("a message", { println("this is a message: $it") } )
//or 
foo("a message")  { println("this is a message: $it") }

   

Now, lets say we have the following function:

fun buz(m: String) {
   println("another message: $m")
}

Is there a way I can pass "buz" as a parameter to "foo" ? Something like:

foo("a message", buz)

Kotlin Solutions


Solution 1 - Kotlin

Use :: to signify a function reference, and then:

fun foo(msg: String, bar: (input: String) -> Unit) {
    bar(msg)
}

// my function to pass into the other
fun buz(input: String) {
    println("another message: $input")
}

// someone passing buz into foo
fun something() {
    foo("hi", ::buz)
}

Since Kotlin 1.1 you can now use functions that are class members ("Bound Callable References"), by prefixing the function reference operator with the instance:

foo("hi", OtherClass()::buz)

foo("hi", thatOtherThing::buz)

foo("hi", this::buz)

Solution 2 - Kotlin

About the member function as parameter:

  1. Kotlin class doesn't support static member function, so the member function can't be invoked like: Operator::add(5, 4)
  2. Therefore, the member function can't be used as same as the First-class function.
  3. A useful approach is to wrap the function with a lambda. It isn't elegant but at least it is working.

code:

class Operator {
    fun add(a: Int, b: Int) = a + b
    fun inc(a: Int) = a + 1
}

fun calc(a: Int, b: Int, opr: (Int, Int) -> Int) = opr(a, b)
fun calc(a: Int, opr: (Int) -> Int) = opr(a)

fun main(args: Array<String>) {
    calc(1, 2, { a, b -> Operator().add(a, b) })
    calc(1, { Operator().inc(it) })
}

Solution 3 - Kotlin

Just use "::" before method name

fun foo(function: () -> (Unit)) {
   function()
}

fun bar() {
    println("Hello World")
}

foo(::bar) Output : Hello World

Solution 4 - Kotlin

Kotlin 1.1

use :: to reference method.

like

    foo(::buz) // calling buz here
    
    fun buz() {
        println("i am called")
    }

Solution 5 - Kotlin

If you want to pass setter and getter methods.

private fun setData(setValue: (Int) -> Unit, getValue: () -> (Int)) {
    val oldValue = getValue()
    val newValue = oldValue * 2
    setValue(newValue)
}

Usage:

private var width: Int = 1

setData({ width = it }, { width })

Solution 6 - Kotlin

Jason Minard's answer is a good one. This could also be achieved using a lambda.

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}

val buz = { m: String ->
    println("another message: $m")
}

Which can be called with foo("a message", buz).

You can also make this a bit more DRY by using a typealias.

typealias qux = (m: String) -> Unit

fun foo(m: String, bar: qux) {
    bar(m)
}

val buz: qux = { m ->
    println("another message: $m")
}

Solution 7 - Kotlin

Here is simple example where I pass the multiplication function as parameter to another function.

fun main(){
    result(10,3,::multiplication)// pass function as parameter wow kotlin amazing
}
fun multiplication(first:Int,second:Int):Int{
    return first*second
}
fun result(firstOne:Int,secondOne: Int,fn:(Int,Int)->Int){
    val result=fn(firstOne,secondOne)
    print(result)

}

Solution 8 - Kotlin

Solution 9 - Kotlin

You can also do this inline using a lambda if that is the only place you are using that function

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}

foo("a message") {
    m: String -> println("another message: $m")
}
//Outputs: another message: a message

Solution 10 - Kotlin

Another example:

 fun foo(x:Int, Multiply: (Int) -> (Int)) {
    println(Multiply(x))
 }
 fun bar(x:Int):Int{
    return  x * x
 }
 foo(10, ::bar)

Solution 11 - Kotlin

First-class functions are currently not supported in Kotlin. There's been debate about whether this would be a good feature to add. I personally think they should.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmhshamsView Question on Stackoverflow
Solution 1 - KotlinJayson MinardView Answer on Stackoverflow
Solution 2 - KotlinRui ZhouView Answer on Stackoverflow
Solution 3 - KotlinerluxmanView Answer on Stackoverflow
Solution 4 - KotlinConnecting life with AndroidView Answer on Stackoverflow
Solution 5 - KotlinCoolMindView Answer on Stackoverflow
Solution 6 - KotlinfleskView Answer on Stackoverflow
Solution 7 - KotlinAnwar ZahidView Answer on Stackoverflow
Solution 8 - KotlinmhshamsView Answer on Stackoverflow
Solution 9 - KotlinkooskoosView Answer on Stackoverflow
Solution 10 - KotlinErik K.View Answer on Stackoverflow
Solution 11 - KotlinajselvigView Answer on Stackoverflow