Kotlin学习笔记——Lambda表达式

lambda 表达式与匿名函数是“函数字面值”,即未声明的函数, 但立即做为表达式进行传递。在Java 8中也开始支持Lambda表达式。

Lambda表达式语法

lambda 表达式由花括号括起来, 包含完整语法形式的参数声明,参数声明有可选的类型标注, 函数体跟在一个 -> 符号之后。如果可以推断出的该lambda表达式的返回类型不是 Unit,那么该 lambda 主体中的最后一个表达式(主体可能只有一个表达式)会视为返回值。

// 格式
{[...] -> body}

// 示例
val sum: (Int, Int) ->Int = {x: Int, y: Int -> x + y} // 前面是个函数类型变量,等号后面是lambda表达式用来初始化该变量
  1. 对于以上的示例,xy是参数,x + y是主体(只有一个表达式),该表达式返回值类型不是Unit,所以最后一个表达式(x + y)会视为lambda表达式的返回值;
  2. sum是函数类型变量,函数类型变量中已经声明了参数和返回值的类型,那么使用lambda初始化该变量时,可以忽略掉lambda表达式中参数列表中参数的类型,可简写成val sum: (Int, Int) -> Int = {x, y -> x + y}

Lambda表达式初始化函数类型参数

函数类型可以通过Lambda表达式进行初始化

val sum: (Int, Int) -> Int = {x: Int, y: Int -> x + y} 
  1. sum是函数类型变量,函数类型变量中已经声明了参数和返回值的类型,那么使用lambda初始化该变量时,可以忽略掉lambda表达式中参数列表中参数的类型,可简写成val sum: (Int, Int) -> Int = {x, y -> x + y}

Lambda表达式作为高阶函数的参数

// com函数的第三个参数z是一个函数类型的变量
fun com(x: Int, y: Int, z: (Int, Int) -> Int): Int {
    return z(x, y)
}

println(com(3, 55, {x: Int, y: Int -> x + y})) // lambda表达式作为高阶函数的参数

println(com(3, 55){x: Int, y: Int -> x + y}) // 如果高阶函数的最后一个参数是lambda表达式,可以将lambda表达式放到参数括号后面,这种语法也叫做拖尾lambda表达式

val sum = {x: Int, y: Int -> x + y} // 定义lambda表达式是,如果无法推断出参数的类型,参数类型不可省略
println(com(3, 55, sum)) // 如果高阶函数最后一个参数是lambda表达式变量,不可放在参数括号后面

Lambda单个参数的隐式名称:it

只有一个参数在 lambda 表达式是很常见的,如果编译器自己可以识别出签名,也可以不用声明唯一的参数并忽略 ->。 该参数会隐式声明为 it

  • 表达式只有一个参数
  • 表达式的签名可以被编译器推断出
  • 在主体中,参数只能用it表示
val validate: (Int) -> Boolean = {it > 0} 

上面的例子中,只有一个参数,根据函数类型的声明,编译器可以识别出lambda表达式的签名,所以省略了lambda表达式中的参数和->,上面表达式等同于val validate: (Int) -> Boolean = {x: Int -> x > 0}

从lambda表达式中返回一个值

  • 如果lambda表达式的返回值不是Unit,又没有指定返回值,默认将最后一个表达式作为返回值。
val sum: (Int, Int) -> Int = {x, y -> x + y } // 默认返回值是`x + y`这个表达式的结果
  • lambda 表达式语法没有指定函数的返回类型的能力,一般是可以通过表达式进行推断,如果无法推断,可以使用匿名函数来实现(匿名函数的函数体可以是语句,也可以是代码块)

代码块作为lambda表达式的主体部分

上面提到lambda表达式没有指定返回值类型的能力,那么需要返回特定类型的值,就需要在主体代码中实现。

  • run{}进行包裹的代码块作为lambda表达式主体实现指定返回值类型,泛型R是可选,如果没有返回值,可以不指明类型(默认Unit),如果有返回值可指定返回值类型,在代码块中,返回值无需return关键字,最有一个表达式语句的结果即为返回值。
val sum = {x: Int, y: Int -> run<Int> {
        val s = x + y
        // 返回值时不能用return,最后一个表达式为返回值,所以这里必须使用if-else的语句组合(不能省去else,否则最终的返回值都是s)
        if(s < 0) {
            0
        } else {
            s 
        }
    }}
  • 使用匿名函数作为lambda表达式主体实现指定返回值类型,应为函数是可以指定返回值类型的,当使用函数作为lambda表达式主体时,也就为lambda表达式指定了返回值
// 匿名函数作为lambda表达式的主题,在匿名函数中指定返回值
val sum = {x: Int, y: Int -> fun(x: Int, y: Int): Int {
        val s:  Int = x + y
        if(s < 0) {
            return 0
        }
        return s
    }}

你可能感兴趣的:(Kotlin学习笔记)