wordpress 微网站模板怎么用,外贸营销型建站,市场营销是学什么,西宁手机网站微站建设Lambda和高阶函数
本文链接#xff1a; 文章目录 Lambda和高阶函数 lambda输出#xff08;返回类型#xff09;深入探究泛型 inline原理探究 高阶函数集合、泛型自己实现Kotlin内置函数 扩展函数原理companion object 原理 静态内部类函数式编程 lambda
1、lambda的由…Lambda和高阶函数
本文链接 文章目录 Lambda和高阶函数 lambda输出返回类型深入探究泛型 inline原理探究 高阶函数集合、泛型自己实现Kotlin内置函数 扩展函数原理companion object 原理 静态内部类函数式编程 lambda
1、lambda的由来
单词lambda源于希腊字母λ小写lambdaLambda一词最早起源于数学中的λ演算lambda calculus它是一种函数定义和函数应用的形式系统由逻辑学家阿隆佐·邱奇Alonzo Church在20世纪30年代发明。邱奇使用λ作为演算中的一个操作符用于表示匿名函数。他选择使用希腊字母λ的原因是因为它在字母表中的位置不太常见这样可以避免与其他符号混淆。
2、函数的声明 // 函数的声明val method01:()-Unitval method02:(Int, Int)-Unitval method03:(String, Double)-Any // 相当于Objectval method04:(String, Double, Float)-Boolean
3、kotlin中Any和Java的Object有什么区别吗
Any是所有非空类型的超类型类似于Java中的Object。Object不能持有null。Any?是所有类型的超类型包括可空类型。 Any?可以持有null值
4、函数如何调用/函数的实现lambdainvoke是什么
// 函数变量通过invoke()调用
// ()是运算符重载
// 函数的实现
val method01:()-Unit
method01 { println(我实现了method01) }
method01() // 调用函数操作符重载
method01.invoke() // 调用函数真实方法// 方法三的实现
val method03:(String, Double)-Any // 相当于Object
method03 {name, number -println($name $number)name number
}
println(method03(wch, 1234567.89))5、函数的实现传入函数
val method04:(String, Double, Float)-Boolean fun(name:String, number:Double, age:Float):Boolean (namenumberage).isEmpty()
method04(wch, 376.23, 1234.5f)6、单一参数的lambda默认持有it 函数式接口 SAM val method05:(Int)-Unit {print($it)}7、下划线可以拒收 拒收 val method06:(Int, Int)-Unit { _, number-println($number)}8、作用是什么
节省空间接口版本变化有的参数没用了
9、想要允许参数为null需要用可空类型如String?
val method07:(String?,String)-Unit {sex, name - println($sex,$name)}method07(null, wch)10、Lambda不可以使用泛型作为参数类型 11、Lambda参数不可以给默认值 默认参数 12、Lambda Any-Any // 传入什么打印什么还可以返回任何东西val method18:(Any)-Any{println($it)it // 还可以返回自己}13、Lambda配合扩展方法 扩展方法 官网写的Funciton但是接收receiver val method19: String.()-Unit {// this String本身 调用者本身println(你是$this)}WCH.method19()14、为什么method19可以成为String的扩展方法
代码val method19: String.()-Unit { ... }表示定义了一个接收者类型为String的扩展函数类型。String.()-Unit表示该函数类型接收一个String作为接收者并返回Unit类型即没有返回值。进一步理解 匿名扩展函数
val method18: ()-Unit; // 类型是 函数
val method19: String.()-Unit // 类型是 String的扩展函数
val method20: (String)-Unit // 类型是 函数该函数的参数是String15、进一步融合this和it区分扩展函数 和 参数的区别
val method20: Int.(Int) - String {两数相加的结果:${thisit}}
println(1.method20(10))println(method20(1, 10)) // 1, 可以自动插为第一个参数函数的形式
fun Int.method21(n:Int):String{return 两数相加的结果:${thisn}
}
println(2.method21(22))
// println(method21(2, 22)) // 不可以这样写了输出返回类型
1、Lambda的返回类型函数 /*** 函数**/// 默认Unitfun t01(){ println() }// 默认Unitfun t02(){4652342.5f}// 默认Unitfun t03(){Hello!}// String显式指明返回值fun t04():String{return feather} // return 还不支持自动推断类型2、函数返回函数 /*** 函数返回函数**/// ()-Unitfun s01() {}fun s02() { println(Haha) }s02()() // 输出// Booleanfun s03() run{ true }// 返回的是代码块的最后一行s03()// ()-Stringfun s04():()-String {Hello}println(s04()) // Function0java.lang.Stringprintln(s04()())3、Java中Lambda是假的
深入探究
4、Lambda深入探究 // k01()返回的类型是: (Int)-Unitfun k01() {n:Int - println(n) }k01()(123)// lambda使用第一种用的多val methodx2 {str:String - str.length}val methodx2s:(String)-Int {it.length}5、Kotlin的Lambda如何和Java兼容源码机制
kotlin编译器实现(很强大) - JVM字节码package kotlin.jvm.functions中定义了Function系列最多Funciton22高版本编译器可以处理22个参数的情况低版本会出错
// val methodx2 {str:String - str.length}
Function1 methodx2 (Function1)null.INSTANCE;// (String)-Unit
val method3:Function1String, Unit { println(it) }6、Lambda考题 //(Int,Int) - (Int,Int) -Stringval funX10 fun(n1:Int,n2:Int):(Int,Int)-String{n1,n2 - 两个数相加:${n1 n2}}println(funX10(10, 10)(20, 20))// 迷惑点最外层的n1和n2和内层的n1 n2没关系// 函数的函数的函数的函数val k01: (String) - (Boolean) - (Int) - (Float) - Double { it -{ it -{ it -{ it -123.456}}}}println(k01(AAA)(true)(45)(67.89f))7、下面的study02()返回的类型是什么
fun study02() {lambda:(Int, Int) - String, studyInfo: String -lambda(1, 99)
}
// 答案((Int, Int) - String, String) - Unit // 使用
study02()({n1, n2- $n1 $n2 ${n1 n2} }, wch)8、下面study04()返回的类型是什么
fun study04() {str:String, num:Int, lambda1:(String)-Unit, lambda2:(Int)-Boolean-lambda1(str)lambda2(num)
}
// 答案(String,Int,(String)-Unit,(Int)-Unit)-Boolean// 使用
println(study04()(wch, 123, { println($it lambda1) }, { it 99}))泛型
9、下面返回的类型是什么
fun T1, T2, R1, R2 study05() {str:T1, num:T2, lambda1:(T1)-R1, lambda2:(T2)-R2 -lambda1(str)lambda2(num)
}
// (T1, T2, (T1)-R1, (T2)-R2) - R2// 使用
study05String, Int, Boolean, Float()(wch, 22, {it.isEmpty()}, {it.toFloat()})10、下面的study06不是lambda是函数。他们的类型是什么
fun study05() {Str:String, num: Int, lambda:(Int)-Boolean -lambda(num)
}
// (String, Int, (Int)-Boolean)-Booleanfun study06() fun(Str:String, num: Int, lambda:(Int)-Boolean):Boolean{return lambda(num)
}
// (String, Int, (Int)-Boolean)-BooleanLambda表达式最后一行作为返回值函数最后一行不能作为返回值必须显式return必须显式指定
函数有隐式的Unit类型返回值
inline原理探究
1、Lambda为什么要内联
不使用内联会构造出Function0对象作为参数传入代码内联减少方法调用开销不再需要创建Function0对象 内存抖动
fun main() {show{println(Hello Kotlin!)}
}
fun show(lambda:()-Unit){lambda()
}
// 不使用内联生成代码
show((Function0)null.INSTANCE);
public static final void show(NotNull Function0 lambda) {Intrinsics.checkNotNullParameter(lambda, lambda);lambda.invoke();
}
// 使用内联
int $i$f$show false;
int var1 false;
String var2 Hello Kotlin!;
System.out.println(var2);高阶函数 Compose内部实现学习
1、高阶函数是什么高阶函数 lambda 函数
fun a() {}
val a1 {} // 函数引用接收匿名函数
val a2 a1 // 函数引用
val a3 ::a // 将函数变成函数引用2、高阶函数就是函数的函数函数中有lambda
// Lambda开胃菜// 返回Stringfun show01(number:Int, lambda:(Int)-String) lambda.invoke(number)// 调用函数var r01 show01(99){it.toString()}// return Intfun show02(n1:Int,n2:Int,n3:Int, lambda: (Int,Int,Int)-Int) lambda(n1, n2, n3)show02(10, 20, 30){i, i2, i3 -i i2 i3}3、高阶函数例子
// 第一版高阶函数应用
fun main() {loginEngine(wch, 123456)
}private fun loginEngine(name:String, pwd:String){loginServer(name, pwd){code, msg-print(错误码$code 错误信息$msg)}
}private fun loginServer(name:String, pwd:String, lambda:(Int, String)-Unit){if(name.isEmpty() || pwd.isEmpty()){lambda(-1, Empty)return}lambda(1, Success)
}
// 第二版4、高阶函数
// 一给泛型增加匿名扩展函数
funT T.myRun01(block: T.(Float) - Boolean) block(123.45f)
// this T本身 调用者本身 Derry// 使用
Derry.myRun01 {isEmpty()
}// 二
funT T.derry4(number:Double, mm: T.(Double) - Unit){mm(number)
}
Derry.derry4(123.456){// this 调用者println(this)
}// 三
funT T.myRunPlus(block: T.(T, T) - Boolean) block(this,this)5、T.() - Boolean s是什么意思
对T扩展出匿名函数匿名函数是 ()-Boolean该匿名扩展函数只有这个高阶函数可以使用其他地方用不出来
6、多个lambda调用
// (一)
show2(lambda1 {}, lambda2 {})
//二
show2({}, {})
// (三
show2({println(Hello)}){println(World!)
}7、源码使用高阶函数利用函数引用
show(::lambdaImpl)fun lambdaImpl(){println(HAHA)
}// 函数引用场景
fun lambdaImpl(name:String):Unit{println(name)
}
var r1:Function1String, Unit ::lambdaImpl
var r2:(String)-Unit ::lambdaImpl
var r3:String.()-Unit ::lambdaImpl // (String)等价于String.()集合、泛型
1、Lambda集合泛型
class AndroidClickListenerT{// 1. 集合的元素类型是Lambda并且Lambda输入参数的类型是 Tval actions arrayListOf(T)-Unit()val actions2 arrayListOf(T?)-Unit() // 可空// 2. 集合的元素类型为泛型val values arrayListOfT?()// 3、设置监听fun addListener(value:T?, lambda:(T?)-Unit){values value // 运算符重载actions2 lambda}// 4、通知观察者fun notify(value:T?){val index values.indexOf(value)actions2[index].invoke(value) // 执行方法actions2[index](value) // 执行方法二}// 5. 模拟点击事件通知所有观察者fun touchListeners(){actions2.forEachIndexed{index, function - function(values[index])}}
}// 使用测试val click AndroidClickListenerString()click.addListener(HaHa){println(接收到数据$it)}click.addListener(WCH){println($it 在吃饭中...)}click.addListener(Feather){println(百万博客主$it)}click.touchListeners()// 函数引用版本fun method(value:String?){println(value)}click.addListener(Hello, ::method)2、如何用变量接收类型中包含泛型的函数
funT method(value: T?):Unit{println(value)
}// 不可以用泛型
// val error:(T?)-Unit ::method// Any来代表T?val m1:(Any)-Unit ::methodm1(Hello)// 具体类型也可以val m2:(Int)-Unit ::methodm2(123)自己实现Kotlin内置函数
1、forEach
// 定义
inline funE IterableE.mForEach(lambda:(E)-Unit){for(item in this)lambda(item)
}// 使用
listOf(AAA, BBB, CCC).mForEach{println(it)}2、let和run为什么会有this为什么会有it
thisitT.()-R, this是对T的匿名扩展函数拥有this(T)-Rit是参数类型SAM单一抽象接口函数式接口it
public inline fun T, R T.run(block: T.() - R): R {return block()
}
public inline fun T, R T.let(block: (T) - R): R {return block(this)
}3、thread
注意点: corssinline
// 自己实现thread特定lambda不能inline
inline fun thread(start:Boolean true,name:String?null,crossinline runAction:()-Unit // 限制不能inline会copy大量代码
):Thread{val thread object:Thread(){override fun run() {super.run()runAction()}}if(start) thread.start() // name?.let { thread.name it } // kotlin形式return thread
}扩展函数原理
1、扩展函数就是构造static final方法将对象作为返回值
class MyKt {}
fun MyKt.show() println(this)public final class MyKt {}
// 构造出Kt类添加扩展函数名一样的static final方法将类的对象作为参数
public final class MyKtKt {public static final void show(NotNull MyKt $this$show) {Intrinsics.checkNotNullParameter($this$show, $this$show);System.out.println($this$show);}
}2、思考叫做扩展函数是否是因为没有receiver
companion object 原理 静态内部类
1、为什么叫伴生对象
生成静态内部类生成静态成员变量类变量通过伴生对象实例调用方法和获取字段
2、使用处
class MyKt {companion object{fun show(){println(this)}val name wch}
}fun main() {MyKt.show()MyKt.name
}3、反编译生成源码
生成静态内部类Companion并且有show()方法和字段name类中Companion实例是static final变量像Java一样调用类方法和获取类属性本质通过Companion伴生对象调用方法和get字段
public final class MyKt {private static final String name wch;public static final Companion Companion new Companion((DefaultConstructorMarker)null);public static final class Companion {public final void show() {System.out.println(this);}public final String getName() {return MyKt.name;}private Companion() {}// $FF: synthetic methodpublic Companion(DefaultConstructorMarker $constructor_marker) {this();}}
}// 使用处
MyKt.Companion.show();
MyKt.Companion.getName();函数式编程
Kotlin函数式编程
链式调用非常丰富的函数库模仿RxJava的响应式编程