Kotlin 高阶函数与 lambda 表达式

Kotlin使用lambda 表达式促成

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

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

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

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

1、高阶函数

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

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

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

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

分类:

  • () -> R,         表示无参返回R类型的函数

    // () -> 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类型的函数

    // (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类型值的函数

    // 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参数一个代码块参数的函数
    //接收(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

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

3、Lambda 表达式

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

语法

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

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

拖尾 lambda 表达式:

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

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

单个参数的隐式名称:it 

// 字面值是“(it: Int) -> Boolean”类型的
val aaa = { it > 0 }

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

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

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

下划线:接收变量

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

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

// lamba 形式
fun(x: Int, y: Int): Int = x + y

// 函数形式
fun(x: Int, y: Int): Int {
    return x + y
}

 

 

你可能感兴趣的:(kotlin)