Kotlin->Kotlin高阶函数和lambda表达式
·
三种函数的调用方式
- 具名函数
// 要写return,要写函数名,不写return默认返回Unit,支持带默认值的调用
fun fun0(age: Int= 26 , name: String) : Int {
println("你的姓名是:$name, 你的年龄是:$age")
return 200
}
// 调用方式
fun0(name ="yang")
// log result
你的姓名是:yang, 你的年龄是:26
- 匿名函数
// 要写return,不写函数名,不写return默认返回Unit,不支持带默认参数的调用
val fun1 = fun(age: Int, name: String): Int {
println("你的姓名是:$name, 你的年龄是:$age")
return 200
}
// 调用方式
fun1(26, "yang")
// log result
你的姓名是:yang, 你的年龄是:26
- lambda表达式
// 不写函数名,不写return,不支持带默认参数的调用
val lambda1 = { age:Int, name :String ->
println("你的姓名是:$name, 你的年龄是:$age")
200
}
// 调用方式
lambda1.invoke(26, "yang")
// log result
你的姓名是:yang, 你的年龄是:26
Kotlin高阶函数
- 返回单个值的通用格式:
lambda表达式名字: (参数1类型,参数2类型…)->返回值类型
// 函数作为方法参数传递
inline fun fun2(age:Int, name :String, action : (Int, String) ->Int /*1. 声明lambda表达式 */){
action(age, name) /*2. 使用lambda表达式*/
}
// 第一种调用方式
fun2(26, "yang", action = { age, name ->
println("你的姓名是:$name, 你的年龄是:$age")
200 /*3. 实现lambda表达式*/
})
// 第二种调用方式
fun2(27, "yang", { age, name ->
println("你的姓名是:$name, 你的年龄是:$age")
200 /*3. 实现lambda表达式*/
})
// 第三种调用方式
fun2(28, "yang"){ age, name ->
println("你的姓名是:$name, 你的年龄是:$age")
200 /*3. 实现lambda表达式*/
}
// 第四种调用方式
fun fun2_0(age:Int, name :String) : Int{
println("你的姓名是:$name,你的年龄是:$age")
return 200 /*3. 实现lambda表达式*/
}
fun2(29, "yang", ::fun2_0)
// log result
你的姓名是:yang, 你的年龄是:26
你的姓名是:yang, 你的年龄是:27
你的姓名是:yang, 你的年龄是:28
你的姓名是:yang, 你的年龄是:29
- 返回单个函数
fun fun3(_age: Int, _name: String) : (Int, String) -> Unit = {
age, name -> println("你的姓名是:$_name, 你的年龄是:$_age")
}
println(fun3(29, "never"))
println(fun3(29, "never")(28, "yang"))
// log result
(kotlin.Int, kotlin.String) -> kotlin.Unit
你的姓名是:never,你的年龄是:29
kotlin.Unit
Kotlin内置函数
apply,T来调用apply,{}里默认持有this,返回T调用者
public inline fun <T> T.apply(block: T.() -> Unit): T {
// this没有传递给lambda表达式,lambda表达式持有this
this.block()
return this
}
run,T来调用run,{}里默认持有this,返回block的lambda表达式的返回值类型R
public inline fun <T, R> T.run(block: T.() -> R): R {
// this没有传递给lambda表达式,lambda表达式持有this
return block()
}
also,T来调用laso,{}里默认持有it,返回lambda表达式返回值
public inline fun <T> T.also(block: (T) -> Unit): T {
// this传递给lambda表达式,lambda表达式持有it
block(this)
return this
}
let,T来调用let,{}里默认持有it,返回block的lambda表达式的返回值类型R
public inline fun <T, R> T.let(block: (T) -> R): R {
// this传递给lambda表达式,lambda表达式持有it
return block(this)
}
takeIf,T来调用takeIf,{}里默认持有it,lambda表达式返回true返回T,否则返回null
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
return if (predicate(this)) this else null
}
takeUnless,T来调用takeUnless,{}里默认持有it,lambda表达式返回true返回null,否则返回T
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
return if (!predicate(this)) this else null
}
Kotlin内联函数
inline- 替换代码,减少函数调用栈,增加编译效率,不适合业务逻辑复杂的大段代码
- 可以外部返回,中断整个业务
- 可以内部返回,不中断整个业务
inline fun inlineFun(param1: Int, param2: String, func: (Int, String)->Unit) {
func(param1, param2)
}
// 使用方式
println("main start")
inlineFun(26, "yang") { param1, param2 ->
println("inlineFun start")
""
println("inlineFun end")
return // 外部返回,中断整个业务
}
println("main end")
// log result
main start
inlineFun start
inlineFun end
// 使用方式
inlineFun(26, "yang") { param1, param2 ->
println("inlineFun start")
""
println("inlineFun end")
return@inlineFun // 内部返回,不会中断整个业务
}
println("main end")
// log result
main start
inlineFun start
inlineFun end
main end
noinlineinline修饰函数中有多个lambda表达式,某个高阶函数的lambda表达式传递给其他非内联函数的参数列表时使用- 这里
fun3能接收fun2是因为noinline关键字
inline fun noInlineFun(fun1: (Int) -> Unit, noinline fun2: () -> Unit) {
fun1(26)
fun2()
fun3(fun2)
}
fun fun3(fun4: () -> Unit) {
fun4()
}
crossinline- 高阶函数中的
lambda表达式被另外一个lambda表达式调用时,属于间接调用,此时这个lambda表达式中return不知道该中断内部lambda表达式还是外部lambda表达式的业务,所以不能外部返回 - 可以内部返回,不中断整个业务
- 不可以外部返回,中断整个业务
- 高阶函数中的
inline fun /*外部lambda表达式*/ crossInlineFun(crossinline fun1: () -> Unit) {
/*内部lambda表达式*/ Runnable { fun1() }.run()
}
// 使用方式
println("main start")
crossInlineFun {
println("subThread start")
println(".......")
println("subThread end")
return@crossInlineFun
}
println("main end")
// log result
main start
subThread start
.......
subThread end
main end
更多推荐
所有评论(0)