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内置函数

  • applyT来调用apply, {}里默认持有this,返回T调用者
public inline fun <T> T.apply(block: T.() -> Unit): T {
    // this没有传递给lambda表达式,lambda表达式持有this
    this.block() 
    return this
}
  • runT来调用run, {}里默认持有this,返回T调用者
public inline fun <T, R> T.run(block: T.() -> R): R {
	 // this没有传递给lambda表达式,lambda表达式持有this
    return block()
}
  • alsoT来调用laso, {}里默认持有it,返回lambda表达式返回值
public inline fun <T> T.also(block: (T) -> Unit): T {
	// this传递给lambda表达式,lambda表达式持有it
    block(this) 
    return this
}
  • letT来调用let, {}里默认持有it,返回lambda表达式返回值
public inline fun <T, R> T.let(block: (T) -> R): R {
    // this传递给lambda表达式,lambda表达式持有it
    return block(this)
}
  • takeIfT来调用takeIf, {}里默认持有itlambda表达式返回true返回T,否则返回null
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    return if (predicate(this)) this else null
}
  • takeUnlessT来调用takeUnless, {}里默认持有itlambda表达式返回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
  • noinline
    • inline修饰函数中有多个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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值