Rush!!!! After the wave, we in the same article surging river — — bing he “surges, after the wave”

After the previous series of explanations to Kotlin, I believe that you can already have a basic understanding of Kotlin. If you have programming experience with the Java language, you may already be out of basic syntax. Starting with this article, we will explain the advanced operations in the Kotlin language. Lambda syntax is already widely used in Java, and almost every project we develop on Android will include Lambda plug-ins as well, because Lambda really reduces the amount of code. Coincidentally, Kotlin also uses Lambda syntax. In this article, we will explain how to write and use Lambda syntax in detail

directory

I. Introduction to Lambda

As mentioned above, it is widely used in Java, but it was only in Java8 that Lambda expressions were supported. Such expressions are one of the syntactic sugars. Thankfully, Kotlin has supported this syntax since open source came of age.

Lambda expressions are essentially anonymous functions because they are implemented in their underlying implementation. But we don’t have to worry about the underlying implementation when we use it. But Lambda does reduce the amount of code to write, and it also makes the code more concise. Lambda, the foundation of functional programming, is also fairly simple in its syntax. Here is a simple code demonstration to let you understand the brevity of Lambda expressions.

Ex. :

// Here is an example of the most common button click event in Android

mBtn.setOnClickListener(object : View.OnClickListener{

        override fun onClick(v: View?). {

            Toast.makeText(this."onClick",Toast.LENGTH_SHORT).show()

        }

})

Copy the code

Is equivalent to

    mBtn.setOnClickListener { Toast.makeText(this."onClick",Toast.LENGTH_SHORT).show() }

Copy the code

Use of Lambda

As for the use of Lambda, I will explain it from two aspects. One is to first introduce the characteristics of Lambda expressions, and the other is to explain the use of Lambda syntax.

2.1. Characteristics of Lambda expressions

The ancients cloud: want to take, first with it.

To learn Lambda expression syntax, you must first understand its characteristics. Here I summarize some characteristics of Lambda expressions. This will become clear when Lambda syntax and practices are explained below. That is:

  1. LambdaExpressions are always enclosed in braces
  2. Its arguments (if present) are declared before the symbol ‘->’ (parameter types can be omitted)
  3. The function body (if present) follows the symbol ‘->’.

2.2. Lambda syntax

To give you a thorough understanding of Lambda syntax, HERE are three uses. And I’ll give you an example

1.Case with no parameters:

val/varVariable name = {operation code}



2.Case with parameters

val/varVariable name: (Parameter type, parameter type...) -> Return value type = {parameter1, the parameter2. -> Code for operation parameters}



Can be equivalent to the

// The return value type of the expression is derived from the operation code.

val/varVariable name = {parameter1: Type, parameter2: Type... -> Code for operation parameters}



3.Here's an example of a lambda expression as a parameter in a function:

fun test(a : Int, parameter name: (Parameter 1: type, parameter 2: type...)-> Expression return type){... }

Copy the code

Example 1: The case with no parameters

/ / the source code

fun test(a){ println("No parameters")}



/ / lambda code

val test = { println("No parameters")}



/ / call

Test () => The result is: No parameter

Copy the code

Example 2: In the case of parameters, here is a two-parameter example for demonstration purposes only

/ / the source code

fun test(a : Int , b : Int) : Int{

    return a + b

}



// lambda

val test : (Int , Int) - >Int = {a , b -> a + b}

/ / or

val test = {a : Int , b : Int -> a + b}



/ / call

test(3.5) => Result:8

Copy the code

Example 3: when a lambda expression is a parameter in a function

/ / the source code

fun test(a : Int , b : Int) : Int{

    return a + b

}



fun sum(num1 : Int , num2 : Int) : Int{

    return num1 + num2

}



/ / call

test(10,sum(3.5)) // The result is 18



// lambda

fun test(a : Int , b : (num1 : Int , num2 : Int) -> Int) : Int{

    return a + b.invoke(3.5)

}



/ / call

test(10,{ num1: Int, num2: Int ->  num1 + num2 })  // The result is 18

Copy the code

The implementation of this last one may be hard to understand, but please don’t be confused, you will read on, and it will be explained in the following practices and higher-order functions.

After the above examples and syntax introduction, we make a summary:

  1. lambdaExpressions are always enclosed in braces.
  2. Fully definedLambdaAn expression, like syntax 2 in the example above, has its full parameter type annotation, as well as the expression return value. In cases where we omit some type annotations, such as the other type of syntax 2 in the example above. When it concludes that the return value type is not ‘Unit’, its return value is->The type of the last (or only one) expression in the code following the symbol.
  3. In the example above, syntax 3 is expressed as:Higher-order functionswhenLambdaWhen an expression is used as a parameter, only the expression provides the parameter type and return type, so when we call this higher-order function, we need to set the parameter type toLambdaAn expression writes out its concrete implementation.
  4. invoke()Function: represents passThe function variablesCall itself because of the variable in the example abovebIs an anonymous function.

Third, Lambda practice

Now that you know the syntax, you should be able to write and use lambda expressions in general, but the simple syntax is not enough to apply to complex situations in real projects. The following highlights Lambda practices from a few points.

3.1, it

  • itIs notKotlinA keyword (reserved word) in.
  • itIt’s in a function of higher orderLambdaCan be used if the expression has only one argumentitTo use this parameter.itCan be represented asThe implicit name of a single parameter, it isKotlinLanguage convention.

Case 1:

val it : Int = 0  // that is, it is not a keyword in 'Kotlin'. Can be used for variable names

Copy the code

Example 2: The implicit name of a single parameter

// Here is an example of a higher-order function filter, which filters out values that do not meet the criteria.

val arr = arrayOf(1.3.5.7.9)

// Filter out any element in the array whose element is less than 2 and print the first one. The it here stands for each element.

println(arr.filter { it < 5 }.component1())   

Copy the code

Example 3: Write your own higher-order function to use IT

fun test(num1 : Int, bool : (Int) -> Boolean) : Int{

    return if (bool(num1)){ num1 } else 0

}



println(test(10,{it > 5}))

println(test(4,{it > 5}))

Copy the code

The output is:

10

0

Copy the code

In the higher-order test function, which returns an Int, the Lambda expression is conditional on num1. Return 0 if Lambda expression is false, num1 if Lambda expression is false. So when num1 > 5, when the test function is called, num1 = 10 returns 10 and num1 = 4 returns 0.

3.2. Underline (_)

When Lambda expressions are used, an underscore (_) can be used to indicate unused arguments, indicating that the argument is not processed.

This is also useful when iterating through a Map collection.

Ex. :

val map = mapOf("key1" to "value1"."key2" to "value2"."key3" to "value3")



map.forEach{

     key , value -> println("$key \t $value")

}



// When the key is not required

map.forEach{

    _ , value -> println("$value")

}

Copy the code

Output result:

key1      value1

key2      value2

key3      value3

value1

value2

value3

Copy the code

3.3 Anonymous Functions

  • Anonymous functions have the advantage of specifying their return value type explicitly.
  • It’s almost the same definition as a regular function. The difference is that anonymous functions have no function name.

Example: Regular functions

fun test(x : Int , y : Int) : Int = x + y

Copy the code

Example: Anonymous functions

fun(x : Int , y : Int) : Int = x + y

Copy the code

As you can see from the two examples above, anonymous functions differ from regular functions in that one has a function name and one does not.

Example exercise:

// When the return value can be automatically inferred, it can be omitted, just like the function

val test1 = fun(x : Int , y : Int) = x + y 

val test2 = fun(x : Int , y : Int) : Int = x + y

val test3 = fun(x : Int , y : Int) : Int{

    return x + y

}



println(test1(3.5))

println(test2(4.6))

println(test3(5.7))

Copy the code

The output is:

8

10

12

Copy the code

From the above code, we can summarize several differences between anonymous functions and Lambda expressions:

  1. Parameter values of anonymous functions are always passed inside the parentheses. whileLambdaAn expression passes a value. There can be a shorthand that omits the parentheses.
  2. In a do not takeThe labelthereturnStatement, when an anonymous function returns the value of its own function, andLambdaThe return value of an expression is returned from the function that will contain it.

3.4. Numeric value of the function with the receiver

In Kotlin, the ability to invoke Lambda expressions is provided for the specified recipient object. In the body of a function literal, a method on the receiver object can be called without any additional qualifiers. It is similar to extension functions in that it allows access to members of the receiver object within the body of the function.

3.4.1 Anonymous function as receiver type

The anonymous function syntax allows you to specify the recipient type of the function literal directly, which is useful if you need to declare a variable using a function type with a receiver and use it later.

Ex. :

val iop = fun Int.( other : Int) : Int = this + other

println(2.iop(3))

Copy the code

The output is:

5

Copy the code

3.4.2 Lambda expressions as receiver types

The prerequisite for using a Lambda expression as a receiver type is that the receiver type can be inferred from the context.

Example: Here is an official example to illustrate

class HTML {

    fun body(a) { …… }

}



fun html(init: HTML. () -> Unit): HTML {

    val html = HTML()  // Create the receiver object

    html.init()        // Pass the receiver object to the lambda

    return html

}





html {       // The lambda with the receiver starts here

    body()   // Calls a method of the receiver object

}

Copy the code

3.5 the closure

  • The so-calledclosure, that is, the function contains the function, where we can include (LambdaExpressions, anonymous functions, local functions, object expressions). We all know that functional programming is a good programming trend now and in the future. soKotlinIt also has this property.
  • As we all know,JavaClosures are not supported,JavaIs an object – oriented programming language, inJava,objectHe’s a first-class citizen.functionandvariableSecond-class citizens.
  • KotlinClosures are supported in,functionandvariableIt’s a first-class citizen, andobjectIt’s a second-class citizen.

Example: Look at a piece of Java code

public class TestJava{



    private void test(a){

        private void test1(a){  // Error because Java does not support functions containing functions



        }

    }



    private void test2(a){}   Functions in Java can only be included in objects +

}

Copy the code

Example: Look at a piece of Kotlin code

fun test1(a){

    fun test2(a){   // Correct, because Kotlin can nest functions



    }

}

Copy the code

Here’s how Kotlin’s closures are represented.

3.5.1 Carrying status

Example: Let a function return a function with a status value

fun test(b : Int): () - >Int{

    var a = 3

    return fun(a) : Int{

        a++

        return a + b

    }

}



val t = test(3)

println(t())

println(t())

println(t())

Copy the code

Output result:

7

8

9

Copy the code

3.5.2 Reference external variables and change their values

Ex. :

var sum : Int = 0

val arr = arrayOf(1.3.5.7.9)

arr.filter { it < 7  }.forEach { sum += it }



println(sum)

Copy the code

Output result:

9

Copy the code

3.6. Take an example

Write an Item click event for the RecyclerView adapter in Android development

class TestAdapter(val context : Context , val data: MutableList<String>)

    : RecyclerView.Adapter<TestAdapter.TestViewHolder>(){



    private var mListener : ((Int , String) -> Unit)? = null



    override fun onBindViewHolder(holder: TestViewHolder? , position:Int) {

.

holder? .itemView? .setOnClickListener {

mListener? .invoke(position,data[position])

        }



    }



    override fun onCreateViewHolder(parent: ViewGroup? , viewType:Int): TestViewHolder {

        return TestViewHolder(View.inflate(context,layoutId,parent))

    }



    override fun getItemCount(a)Int {

        return data.size

    }



    fun setOnItemClickListener(mListener : (position : Int, item : String) -> Unit) {

        this.mListener = mListener

    }



    inner class TestViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView)

}



/ / call

TestAdapter(this,dataList).setOnItemClickListener { position, item ->

        Toast.makeText(this."$position \t $item",Toast.LENGTH_SHORT).show()

    }

Copy the code

conclusion

Lambda expressions reduce a lot of code for us, but Lambda expressions lay the foundation for later chapters of higher-order functions. Although higher-order functions are also mentioned in this article, they are the most basic. In the following chapters, we will introduce custom higher-order functions and higher-order functions commonly used in Kotlin.

In this chapter, the syntax and use of Lambda are described. And some features and practices of Lambda expressions. Anonymous functions are also included. The most important of these is Lambda’s practice.

This article has been collected on GitHub: Jetictors/KotlinLearn, welcome star articles continue to update, can be wechat search “J guy talk” first time read, everyone’s three-in-one is the best power for the old J, you are sure not to wave? If you have any mistakes or suggestions on this blog, please leave comments


Ah hello, five fingers mushroom niang ah, take a phone to scan!