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:
- Contains actual arguments (a: Int, b: Int)
- Contains the body of the function (even if the body is empty, it must be declared) (a+b)
- 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:
- Pass functions as arguments
- 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:
- Let’s say T, X -> R from the outside in
- 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)