Lambda expressions

function

Let’s start with familiar Java. In Java, functions generally take the form:

public String getString(String input) {}Copy the code
  • If you look at it, the obvious feature is that you have an output, which is a return value of type String, and then you have an input, which is a parameter.

In Kotlin, however, the opposite is true, with input followed by output, as follows:

fun getString(input: String) : String {
    
}
Copy the code
  • The argument written first, followed by the return value, is relatively consistent with the writing convention

Lambda functions

Functions generally include two parts, one is the declaration of the function, the other part is the implementation of the function. Fun getString(input: String) : String is the declaration of the function, and parentheses are the implementation of the function.

So in Kotlin, how do you write a function declaration?

var getString : (String) -> String
Copy the code

If you write the corresponding Java function, it should look like this:

public String getString(String inputStr) 
Copy the code

It is easy to see that kotlin and Java input and output types can be matched, but they are presented in different ways.

So if you return Any instead of String, what is the corresponding return value in Java?

The answer is Object.

In Kotlin, there are no base data types, only reference data types (Int, Double…). , but when decompiled into Java bytecode, it becomes int, double, etc.

So far, only function declarations can not be called directly

How do I write a function that declares + implements

var getString = {
    println("hello kotlin")}Copy the code
  • Above is a function that includes declaration and implementation

If you don’t see it in Kotlin, let’s write the equivalent Java code to look at it and analyze it. The function is simply to print Hello Kotlin:

public void getString(a) {
    System.out.println("hello kotlin");
}
Copy the code

It should be noted that Kotlin’s type derivation helps us omit the type of the function, and actually writes it as follows:

var getString : () -> Unit = {
    println("hello kotlin")}Copy the code

Is there any confusion here as to why the type derivation is () -> Unit?

At this point, just look back at how functions are declared in Kotlin to see why.

Why doesn’t the function here start with fun

  • In fact, this function is an anonymous function, which is assigned to the variable.
  • You can call directly with a variable name or use invoke as follows:
fun main(a) {
    val getString : () -> Unit = {
        println("hello kotlin")
    }

    getString()
    getString.invoke()
}
Copy the code
  • Either method can be called successfully, and here () is actually an overload of the invoke operator.

Var getString = {“this is kotlin”

Run the code above to see what happens

fun main(a) {
    val getString = {
        "hello kotlin"
    }

    print(getString.invoke())
}
Copy the code
  • The result is hello Kotlin.
  • In parentheses, the last line will be the return value. If you change the code to look like this
fun main(a) {
    val getString = {
        "hello kotlin"
        Awesome!
    }

    print(getString.invoke())
}
Copy the code

The return value is 666. If the last line is a function, then it’s a function of functions, a higher-order function.

A little bit more complicated

val testPlus = {number1: Int, number2: Int -> number1 + number2}
Copy the code
  • This function uses number1 and number2 as two arguments, number1+number2, and returns an Int. Equivalent to Java
public int testPlus(int number1, int number2) {
    return number1 + number2;
}
Copy the code

A little bit more complicated

As mentioned earlier, functions have two parts: declaration and implementation. Then it’s natural to declare and implement.

First statement:

val getString : (Int) -> String
Copy the code

To achieve:

getString = fun(number) = number.toString()
Copy the code
  • When declared, the argument type is Int and the return value is String. When implemented, number is automatically derived as an int, and the implementation returns a String. If toString is replaced with toShort, the compiler will report an error.

If taken as a whole, it looks like this:

fun main(a) {
    val getString : (Int) -> String = fun(number) = number.toString()
    getString
}
Copy the code

Tip: Hover over the getString call and press Shift+Ctrl+P to see the arguments and return values of getString.

So, what’s the advantage of writing this?

Except to install B, is probably no other use.

The final form of hui

Declaration and implementation, how do you write it

val getString : (Int, String) -> String = {values, str -> "value is $values str is $str"}
Copy the code
  • Values are Int, STR is String, and the return value is String

Can you simplify it a little bit more

Yes, but only with one parameter

val getString : (String) -> Unit = {
    println("string  is $it")}Copy the code
  • As stated above, a STR -> should appear after the braces, but since there is only one argument, you can use it instead.

In Kotlin, most of these are expressions, such as if and when, which can be returned, whereas in Java, if and so on are statements that cannot be returned

So when you have two or more arguments, can you abbreviate them

fun main(a) {

    val getString : (String, String) -> Unit = {_,str2 ->
        println("str is $str2")}}Copy the code
  • GetString takes two parameters, but as long as the second parameter is used, the first parameter can be replaced by _.
  • This way, the first argument is not generated inside the method, reducing space usage