Preface This blog is my study notes, if there is something wrong, please point out in the comment area, please forgive me

Kotln Study Notes (8)

Refer to the article

Lambda expressions

A lambda is simply an anonymous function. I’ll show you the different ways of expressing it in the code here


// This is the first time that I have been able to do this
fun  (a :Int , b : Int):Int{
        return a + b
    }

// You can use = to omit the braces
fun  (a :Int , b : Int):Int = a + b

// Intelligent type
fun  (a :Int , b : Int) = a + b

// The original version of the Lambda expression
val lambda = {
	
	// The type and parameters passed in
	
    a : Int , b : Int

	// -> split input and output
    
           ->

	// Output results
   
    a+b
}



// Lambda expression. Both reference methods are correct, but they are essentially the same
println(lambda(2.3))
println(lambda.invoke(2.3))

Copy the code

The standard form basic declaration of lambda satisfies three conditions:

  1. Contains actual arguments (a: Int, b: Int)
  2. Contains the body of the function (even if the body is empty, it must be declared) (a+b)
  3. The above insides must be contained within curly braces

Most anonymous classes, of course, are one-parameter classes, and we’re going to use a one-parameter lambda equation for the brief demonstration here.

/ / declare
var sum : ((Int) - >Int)? = null

/ / implementation

// {parameter: parameter type -> return value (concrete logic)}
sum ={x : Int  -> x*2}

// We can also omit the parameter types since we know the input types
sum ={x -> x*2}

// Since we use a parameter, the parameter can be written as it
sum ={it*2}

// If the lambda expression is incorrect, return cannot be used directly within it
sum ={
        it*2
        return
    }

// The last expression is the return value of the expression
sum ={
        println("$it")
        it*2
    }
Copy the code

Matters needing attention Note: : Syntax simplification is a double-edged sword, simplification is good, easy to use, but do not abuse, also need to consider the readability of the code.

1.1 lambda return

We can’t use return in a lambda expression. We can use return+label;

// Declare one with no return value
var demo : ((Int) - >Unit)? = null

demo = die@{
        it *2
        return@die
    }
Copy the code

2. Advanced functions

An advanced function is still a function, except that the parameters of the method can be a function and the return value can be a function. Let’s look at advanced functions using examples

// The second argument to the function is a lambda function

fun play(girl :String , shop : () ->Unit):Unit{
    println("the girl is $girl")

    fun todoSomething (a) :Unit{
        shop()
        println("todoSomething start")}// The return value can also be a function
    
    return todoSomething()
    
}
Copy the code

Explanation: In Kotlin, a function is a type, so we can treat a specific function as an object. Since the function is an object, we can play with it any way we want. Such as:

  1. Pass functions as arguments
  2. Pass the function as the return value

Next, let’s look at high-level function calls


fun shopImpl(a):Unit{
        println("hello world")}// Call a normal function
play("gyy",:: shopImpl)

// Pass the lambda function
play("gyy",{ println("hello world !")})

Copy the code

With that in mind, let’s write an extension function and simply use the advanced function


// Pass the extension function to the lambda function

fun List<Int>.initList(double: (Int) - >Int): List<Int> {
    var resultList  = arrayListOf<Int> ()// Loop through the collection items into the lambda function
    for(item in this){
        resultList.add(double(item))
    }
    return resultList
}


var oneList = arrayListOf<Int> (1.2.3)

// By default, the toString method of List is called
println(oneList)
// Call and define the lambda function
var twoList = oneList.initList { it * 2 }
println(twoList)

Copy the code

Print results’

[1, 2, 3]
[2, 4, 6]
Copy the code

2.2 Type of lambda expressions

Kotlin provides a concise syntax for defining the types of functions.

() -> Unit// Represents a Lambda expression type with no arguments and no return value

(T) -> Unit// represents a Lambda expression type that takes a T parameter and returns no value

(T) -> R// represents a Lambda expression type that takes a parameter of type T and returns a value of type R

(T, P) -> R// represents a Lambda expression type that takes an argument of type T and type P and returns a value of type R

(T, (P,Q) -> S) -> R// represents a Lambda expression type parameter that takes a T parameter and a Lambda expression type parameter that takes P and Q parameters and returns a value of type S, and a Lambda expression type that returns a value of type R

Some readers may be able to understand the first few expression types, but here is the last one

(T, (P,Q) -> S) -> R:

  1. Let’s say T, X -> R from the outside in
  2. X can be understood as (P,Q) -> S

3. The TypeAlias keyword names the type Lambda

If you have multiple lambda expressions, but many of these lambda expressions are of the same type, it’s easy to repeat all the same long list of lambda type declarations or your lambda type declarations are too long to read. Actually, no, for Kotlin, a language that rejects all verbose syntax, provides you with a number of ways to simplify your code without making it less readable. For example

fun main(args: Array<String>) {

        fun List<Int>.initList(double: (Int) - >Int): List<Int> {
            var resultList  = arrayListOf<Int> ()// Loop through the collection items into the lambda function
            for(item in this){
                resultList.add(double(item))
            }
            return resultList
        }

        val oddNum:  (Int) - >Unit = {
            if (it % 2= =1) {
                println(it)
            } else {
                println("is not a odd num")}}val evenNum:  (Int) - >Unit = {
            if (it % 2= =0) {
                println(it)
            } else {
                println("is not a even num")
            }
        }

        oddNum.invoke(100)
        evenNum.invoke(100)


        var oneList = arrayListOf<Int> (1.2.3)

        // By default, the toString method of List is called
        println(oneList)
        // Call and define the lambda function
        var twoList = oneList.initList { it * 2 }
        println(twoList)
    }
Copy the code

Use the TypeAlias keyword to declare (Int) -> Unit and (Int) -> Int types

Package com.ymc.kotlinDemo import android.os.Bundle // TypeAlias Specifies keyword TypeAlias NumPrint = (Int) -> Int TypeAlias Num2Print = (Int) -> Unit fun List<Int>.initList(double: NumPrint): List<Int> {var resultList = arrayListOf<Int>();} for(item in this){ resultList.add(double(item)) } return resultList } val oddNum: Num2Print = { if (it % 2 == 1) { println(it) } else { println("is not a odd num") } } val evenNum: Num2Print = { if (it % 2 == 0) { println(it) } else { println("is not a even num") } }Copy the code

4. Kotlin usage Scenarios

Refer to the article

Scenario 1: Lambda expressions are used with collections, the most common scenario, and have the flexibility to filter, map, transform, and manipulate the collection data.

fun main(args: Array<String>) {
    val nameList = listOf("Kotlin"."Java"."Python"."JavaScript"."Scala"."C"."C++"."Go"."Swift")
    nameList.filter {
        it.startsWith("K")
    }.map {
        "$it is a very good language"
    }.forEach {
        println(it)
    }

}

Copy the code

Scenario 2: Replace the original anonymous inner class, but note that you can only replace a class with a single abstract method. The way we write it in Java is as follows

	findViewById(R.id.submit).setOnClickListener(new View.OnClickListener() {
			@Override
			publicvoid onClick(View v) { ... }});Copy the code

But if you use lambda

findViewById(R.id.submit).setOnClickListener{
    ...
}

Copy the code

Scenario 3: Defining Kotlin extension functions or functions that need to be passed in as values.

fun Context.showDialog(content: String = "", negativeText: String = "Cancel", positiveText: String = "Sure", isCancelable: Boolean = false, negativeAction: (() -> Unit)? = null, positiveAction: (() -> Unit)? = null) {
	AlertDialog.build(this) .setMessage(content) .setNegativeButton(negativeText) { _, _ -> negativeAction? .invoke() } .setPositiveButton(positiveText) { _, _ -> positiveAction? .invoke() } .setCancelable(isCancelable) .create() .show() }fun Context.toggleSpFalse(key: String, func: () -> Unit) {
	if(! getSpBoolean(key)) { saveSpBoolean(key,true)
		func()
	}
}

fun <T : Any> Observable<T>.subscribeKt(success: ((successData: T) - >Unit)? = null, failure: ((failureError: RespException?). ->Unit)? = null): Subscription? {
	return transformThread()
			.subscribe(object : SBRespHandler<T>() {
				override fun onSuccess(data: T){ success? .invoke(data)}override fun onFailure(e: RespException?).{ failure? .invoke(e) } }) }Copy the code

So far, I have concluded my understanding of lambda and advanced functions. If there is any shortage, please comment positively.

Kotlin’s Study Notes (10)