Kotlin extension lambda versus regular lambda

According to the following source code, it seems that regular lambdas are interchangeable with the lambdas extension.

fun main(args: Array<String>) {

    val numbers = listOf(1, 2, 3)

    filter(numbers, predicate)
    filter(numbers, otherPredicate)

    println("PREDICATE: ${predicate} " +
        "\nOTHERPREDICATE: ${otherPredicate} " +
        "\nEQUALITY: ${predicate==otherPredicate}")
}

val predicate : Int.() -> Boolean = {this % 2 != 0}
val otherPredicate : (Int) -> Boolean = {it % 2 != 0}


fun filter(list: List<Int>, predicate:(Int) -> Boolean) {
    for(number in list){
        if(predicate(number)){
            println(number)
        }
    }
}

The output (I care) is as follows:

PREDICATE: kotlin.Int.() -> kotlin.Boolean 
OTHERPREDICATE: (kotlin.Int) -> kotlin.Boolean 
EQUALITY: false

The question is why are these lambdas interchangeable? Shouldn't there be something else? Does the compiler do something smart under the hood?

+4
source share
1 answer

Differences

This is not completely interchangeable, since the "lambdas extension", technically called lambdas with the receiver , can be called on the receiver, which is not possible with regular lambdas:

predicateWithReceiver(2) //OK
2.predicateWithReceiver() //OK

regularPredicate(2) //OK
2.regularPredicate //Not OK

Lambdas , - ( ). , , .. .

. , 2.regularPredicate - ( Java):

  Function1 predicateWithReceiver = ...;
  predicateWithReceiver.invoke(2);

, .

, filter, . , ( Java):

public static final void filter(@NotNull List list, @NotNull Function1 predicate) {

  //...
     if ((Boolean)predicate.invoke(number)) {
        System.out.println(number);
     }
  }

}

Function1. , lambdas reiceiver . , predicate Kotlin.

+3

Source: https://habr.com/ru/post/1693018/


All Articles