Android---Kotlin learning 003

*Anonymous function

Functions that are defined without a name are called anonymous functions. Anonymous functions are usually passed in their entirety to other functions, or returned from other functions . Anonymous functions are very important to Kotlin. With them, we can formulate special rules according to our needs and easily customize the built-in functions in the standard library.

Example:

fun main(){
    val count = "Mississippi".count()
    println(count)

    val countS = "Mississipi".count({letter ->
        letter == 's'
    })
    println(countS)
}

 String.count() The count() API provided in Kt can count the number of characters in a string. Anonymous functions can formulate some special rules for these built-in standard functions (API) . For example, if we count the number of occurrences of the character 's' above, we can pass an anonymous function in the brackets of count(), that is, " {letter -> letter == 's'} "

Function types and implicit returns

Anonymous functions also have types. Anonymous functions can be assigned to function type variables as variables. Just like other variables, anonymous functions can be passed in the code. Variables have types, variables can be equal to functions, and functions also have types . The type of a function is determined by the parameters passed in and the return value type .

Unlike named functions , except in rare cases, anonymous functions do not require the return keyword to return data. Anonymous functions implicitly or automatically return the result of the last line of statement in the function body .

Example:

fun main(){
    // 变量的类型是一个匿名函数,即 冒号 后面的部分
    val blessingFunction : () -> String = {
        val holiday = "New Year."
        "Happy $holiday"
    }
    println(blessingFunction)
}

Explanation: blessingFunction is a variable, and the type of this variable is the type of a function. Because when we define a variable, it is usually: val blessingFunction: String, so the content after the colon ":" is its type, that is, here is a function () -> String (this function has no parameters and the return value is String). As long as it is any anonymous function that has no parameters passed in and the return type is String, it can be equal to the blessingFunction variable. And here we use an anonymous function to assign values, namely 

{
    val holiday = "New Year."
    "Happy $holiday"
}

This anonymous function has no parameters, and the return type is the result of the last row, which is String.

Anonymous function parameters

Like named functions, anonymous functions can take no parameters or take one or more parameters of any type. When parameters are required, the type of the parameter is placed in the type definition of the anonymous function, and the parameter name is placed in the function definition.

Example 1: An Int parameter

fun main(){
    
    val number : (Int) -> Int = {original ->
        val num = 1
        num + 1 + original
    }
    println("The result number is " + number(2))
}

explain:

Example 2: Two parameters, a String name and an Int age.

fun main(){
    val person : (String, Int) -> String = {name, age ->
        "His name is $name, and age is $age"
    }
    println(person("HL", 17))
}

it keyword

When defining an anonymous function with only one parameter, you can use the it keyword to represent the parameter name. When you need to pass in two parameters, the it keyword cannot be used.

Example: replace original with it

type inference

\bullet  When defining a variable, if an anonymous function has been assigned to it as a variable, there is no need to explicitly indicate the variable type.

Omitted:() -> String .

\bullet Type inference also supports anonymous functions with parameters, but in order to help the compiler infer variable types more accurately, the parameter names and parameter types of the anonymous function must be available .

lambda 

We call the anonymous function a lambda, its definition a lambda expression , and the data it returns an ambda result . Why is it called lambda? Lambda can also be represented by the Greek character λ, which is the abbreviation of lambda calculus. Lambda calculus is a set of mathematical calculus logic invented by mathematician Alonzo Church in the 1930s. When defining anonymous functions, Lambda calculus notation is used .

Define a function whose parameters are functions

The parameter of the function is another function. It can be understood as passing an anonymous function as a parameter of a named function.

Abbreviation

If a function's lambda parameter comes last or is the only parameter, the pair of parentheses surrounding the lambda value parameter can be omitted. As shown in the following code: In the compiler, the yellow line is a reminder that we can omit the parentheses. Because there is only one parameter, and it is lambda 

Yellow line disappears

Example 2:

The last parameter in the above code is lambda, so the parentheses surrounding the lambda value parameter are not needed, because lambda is not the only parameter here, so the correct way to write it is to put it outside the parentheses, as shown in the following code

Example 3: If there is only one parameter, whether it is an ordinary parameter or a lambda parameter, the parentheses can be omitted

Note: The omitted writing of the above code is easy for people to misunderstand and understand. So you need to understand more about this shorthand notation in Kt.

Function inlining

Lambdas allow you to write applications more flexibly, but flexibility comes at a price. On the JVM, the lambda you define will exist in the form of an object instance. The JVM will allocate memory for all variables that deal with the lambda, which creates memory overhead. To make matters worse, the memory overhead of lambdas can cause serious performance problems. Fortunately, kotlin has an optimization mechanism called inlining . With inlining, the JVM does not need to use lambda object instances , thus avoiding variable memory allocation. Wherever a lambda needs to be used, the compiler will copy and paste the function body there. Recursive functions using lambda cannot be inlined because it will cause an infinite copy-paste loop and the compiler will issue a warning.

function reference

To pass a function as a parameter to other functions, in addition to passing lambda expressions, Kotlin also provides other methods, passing function references . Function references can convert a named function into a value parameter , and can be used wherever lambda expressions are used. Use function references.

Example:

Explanation: personInfo is a named function, and the second parameter of getPerson is an anonymous function, so a named function can be passed in through a function reference (::function name).

function type as return type

Function types are also valid return types, which means you can define a function that returns a function .

Example:

fun main(){
    val personInfo = getPersonInfo()
    println(personInfo("HL", 17))
}
fun getPersonInfo() : (String, Int) -> String {
    val sex = "男"
    return {name : String, age : Int ->
        "His name is $name, and he is $age years old and $sex."
    }
}

explain:

Note: The number and type of parameters must correspond.

Closure

In Kotlin, anonymous functions can modify and reference variables defined outside their own scope. Anonymous functions refer to variables in the function in which they are defined . Lambdas in Kotlin are closures. As mentioned earlier, anonymous functions are lambdas, and lambdas are closures .

Functions that can receive functions or return functions are also called advanced functions. Advanced functions are widely used in functional programming.

lambdas and anonymous inner classes

Why use function types in your code? Function types allow developers to write less patterned code and write more flexible code . Java 8 supports object-oriented programming and lambda expressions, but does not support passing a function as a parameter to another function or variable, but the alternative in Java is anonymous inner classes .

Example: Java passing function through anonymous inner class

This code has not yet used Java's anonymous inner classes, but instead uses what we are usually familiar with, writing a MyPerson class that inherits from the PersonInfo interface, and then passing a MyPerson object as a parameter when calling getPersonInfo in the main() method.

Explanation: Compared with the traditional writing method above, this code no longer requires a MyPerson class to implement the PersonInfo interface. When calling the getPersonInfo() method, pass new PersonInfo directly as a parameter.  In this way of writing, the PersonInfo interface also has an implementation class, but the name of its implementation class is anonymous, so it is called an anonymous inner class .

The above two ways of writing functions as parameters in Java both have patterned code, that is, the part that writes the interface.

In Kt, there is no need at all, it can be achieved through anonymous functions . For example, the definition parameters mentioned above are the function and abbreviation part of the function

Guess you like

Origin blog.csdn.net/qq_44950283/article/details/134769156