Kotlin 高阶函数与 lambda 表达式

Kotlin使用lambda 表达式促成

  • 可以在变量与数据结构中存储函数

  • 可以作为参数传递给其他高阶函数

  • 可以从其他高阶函数返回

  • 可以像操作任何其他非函数值一样对函数进行操作

1、高阶函数

将函数用作参数或返回值的函数,即高阶函数

高阶函数定义,只需要将参数类型或返回值类型中的任意一个定义为函数类型即可

Kotlin 复制代码
// 参数类型是函数类型
修饰符 函数名(参数名:(T...)-> R) : 返回值类型 {
    ...
    方法体
    ...
    return 返回值;
}
// 返回值类型是函数类型
修饰符 函数名(参数名:参数类型) : (T...)-> R {
    ...
    方法体
    ...
    return 返回值;
}
2、函数类型

格式: (T...)-> R (T、R均表示泛型) T...表示可以有多个形参,R也可以是Unit

分类:

  • () -> R, 表示无参,返回R类型的函数
Kotlin 复制代码
    // () -> R 类型函数声明和定义
    //lamba形式
    val aaa : () -> Int = {444}
    val bbb : () -> Unit = {println("Unit")}
    // 调用函数
    println(aaa())   //  444
    bbb()            //  Uint

    // 函数形式
    fun fun1(n: Int, lamba: () -> Int) : Unit {
        println("$n")            
        println("${lamba()}")  
    }
    // 调用函数
    fun1(111, aaa)
    /*
        111
        444
    */
  • (T) -> R, 表示一个T类型参数,返回R类型的函数
Kotlin 复制代码
    // (T) -> R 类型函数声明和定义
    val aaa : (String) -> Float = {
        println("$it")
        444.0f
    }
    // 调用函数
    println(aaa("hello")) 
    /*
       hello
       444.0
    */

    // 函数形式
    fun fun1(n: Int, lamba: (String) -> Float) : Unit {
        println("$n")            
        println("${lamba("word")}")  
    }
    // 调用函数
    fun1(111, aaa)
    /*
        222
        word
        444.0
    */
  • T.(A) -> R, 表示在 T 的接收者对象上用一个 A类型参数来调用,返回一个 R类型值的函数
Kotlin 复制代码
    // T.(A) -> R 类型函数声明和定义
    val aaa: String.(Int) -> Int = {
        // 传给调用的接收者对象成为隐式的this,
        // 以便访问接收者对象的成员而无需任何额外的限定符,
        // 亦可使用 this 表达式 访问接收者对象
        println("$this $it")
        555
    }
    // 调用函数
    println(aaa("hello", 444)) 
    /*
        hello 444
        555
    */

    // 函数形式
    fun fun1(n: Int, lamba: String.(Int) -> Int) : Unit {
        println("$n")            
        println("${lamba("word", 234)}")  
    }
    // 调用函数
    fun1(111, aaa)
    /*
        111
        word 234
        555
    */
  • (T, T.() -> R),表示接收输入一个T参数和一个代码块参数的函数
Kotlin 复制代码
    //接收(T, T.() -> R) 参数类型的函数声明和定义
	val aaa: (f: Float, s: String.(Int) -> Float) -> Int = {f, s ->
        println("$f")                      // 444.0
        var bb = s("hello", 444)
        println("$bb")                     // hello, 444
        555
    }
    // 调用函数
    var cc = aaa(444.0f){
        println("$this, $it")              // 333.0
        333.0f
    }
    println("$cc")                         // 555

    // 函数形式
    fun fun1(f: Float, s: String.(Int) -> Float) : Int {
        println("$f")                      // 111.0
        var dd = s("word", 234)
        println("$dd")                     // 222.0
        return 123
    }
    // 调用函数
    val ee = fun1(111f) {
        println("$this $it")               // word 234
        222.0f
    }
    println("$ee")                         // 123

函数的参数名可选:(x:Int,y: Int) -> Point;若返回Unit 类型不可省略,表示无返回值

使用圆括号,将函数类型指定为可空: ((Int, Int) -> Int)?

使用圆括号,进行接合:(Int) -> ((Int) -> Unit)

箭头表示法是右结合的:(Int) ->(Int)-> Unit 与前述示例等价,但不等于 ((Int) ->(Int))-> Unit

Kotlin 复制代码
class A
// 下面两个函数的调用方式都一样,都需要传入一个A对象,不同之处在函数体内
val myFun1 = fun A.() { // 在函数体内隐含this,可直接调用T成员变量和函数 }
val myFun2 = fun(a: A) { // 普通函数,必须使用a.的方式显式调用A类内的任意函数和变量 }
3、Lambda 表达式

lambda 表达式是函数字面值,即没有声明而是立即做为表达式传递的函数

语法:

  • lambda 表达式总是括在花括号中
  • 完整语法形式的参数声明放在花括号内,并有可选的类型标注
  • 函数体跟在一个 -> 之后。
  • 返回类型如果推断不是 Unit,则以 { } 里最后一个(或可能是单个)表达式会视为返回值
Kotlin 复制代码
// 完整形式
val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }

// 简写形式
val sum = { x: Int, y: Int -> x + y }

拖尾 lambda 表达式:

Kotlin 复制代码
// 按照 Kotlin 惯例,如果函数的最后一个参数是函数
// 那么作为相应参数传入的 lambda 表达式可以放在圆括号之外
val product = items.fold(1) { acc, e -> acc * e }

// 如果该 lambda 表达式是调用时唯一的参数,那么圆括号可以完全省略
run { println("...") }

单个参数的隐式名称:it

Kotlin 复制代码
// 字面值是"(it: Int) -> Boolean"类型的
val aaa = { it > 0 }

限定返回语法:return@xxx 从 lambda 显式返回一个值,否则,将隐式返回最后一个表达式的值

Kotlin 复制代码
// 两个返回值是一样的
ints.filter {
    val shouldFilter = it > 0
    shouldFilter
}

ints.filter {
    val shouldFilter = it > 0
    return@filter shouldFilter
}

下划线:_ 接收变量

Kotlin 复制代码
// 参数1不使用,那么可以用下划线(_)取代其名称
map.forEach { (_, value) -> println("$value!") }
4、匿名函数

像常规函数一样声明,但省略其名称;当匿名函数作为参数传递时,需将其放在括号内;允许将函数留在圆括号外的简写语法仅适用于 lambda 表达式

Kotlin 复制代码
// lamba 形式
fun(x: Int, y: Int): Int = x + y

// 函数形式
fun(x: Int, y: Int): Int {
    return x + y
}
相关推荐
yzpyzp2 小时前
Kotlin的MutableList和ArrayList区别
android·kotlin
帅次5 小时前
Flutter Container 组件详解
android·flutter·ios·小程序·kotlin·iphone·xcode
帅次9 小时前
Flutter setState() 状态管理详细使用指南
android·flutter·ios·小程序·kotlin·android studio·iphone
移动开发者1号13 小时前
Compose列表项动画实现指南
android·kotlin
移动开发者1号13 小时前
Compose与View系统互操作方案
android·kotlin
heeheeai1 天前
kotlin kmp 副作用函数 effect
kotlin·effect·kmp·副作用函数
纳于大麓1 天前
Kotlin基础语法一
android·开发语言·kotlin
KotlinKUG贵州1 天前
Spring开发,从Kotlin开始
spring boot·spring·kotlin
移动开发者1号2 天前
Android中Activity、Task与Process的关系
android·kotlin
移动开发者1号2 天前
Activity onCreate解析
android·kotlin