Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin function reference

Let records be stream/collection and extract function which transforms data form an element of such collection.

Is there a way in Kotlin to write

records.map {extract(it)} 

without explicitely applying(it) ?

E.g. records.map(extract) or records.map {extract}

like image 801
ps-aux Avatar asked Feb 27 '17 21:02

ps-aux


People also ask

What is function reference in Kotlin?

A function reference is typically used to pass an expression or set of instructions from one part of your code to another. There are a few other ways to accomplish this in Kotlin.

Can you pass by reference in Kotlin?

Since no assignment is possible for function parameters, the main advantage of passing by reference in C++ does not exist in Kotlin.

How do you assign a function to a variable in Kotlin?

You can assign them to variables and constants just as you can any other type of value, such as an Int or a String . This function takes two parameters and returns the sum of their values. Here, the name of the variable is function and its type is inferred as (Int, Int) -> Int from the add function you assigned to it.


1 Answers

  • If extract is a value (local variable, property, parameter) of a functional type (T) -> R or T.() -> R for some T and R, then you can pass it directly to map:

    records.map(extract)
    

    Example:

    val upperCaseReverse: (String) -> String = { it.toUpperCase().reversed() }
    
    listOf("abc", "xyz").map(upperCaseReverse) // [CBA, ZYX]
    
  • If extract is a top-level single argument function or a local single argument function, you can make a function reference as ::extract and pass it to map:

    records.map(::extract)
    

    Example:

    fun rotate(s: String) = s.drop(1) + s.first()
    
    listOf("abc", "xyz").map(::rotate) // [bca, yzx]
    
  • If it is a member or an extension function of a class SomeClass accepting no arguments or a property of SomeClass, you can use it as SomeClass::extract. In this case, records should contain items of SomeType, which will be used as a receiver for extract.

    records.map(SomeClass::extract)
    

    Example:

    fun Int.rem2() = this % 2
    
    listOf("abc", "defg").map(String::length).map(Int::rem2) // [1, 0]
    
  • Since Kotlin 1.1, if extract is a member or an extension function of a class SomeClass accepting one argument, you can make a bound callable reference with some receiver foo:

    records.map(foo::extract)
    records.map(this::extract) // to call on `this` receiver
    

    Example:

    listOf("abc", "xyz").map("prefix"::plus) // [prefixabc, prefixxyz]
    

(runnable demo with all the code samples above)

like image 179
hotkey Avatar answered Sep 23 '22 07:09

hotkey