Kotlin编程之高阶函数,Lambda表达式,匿名函数

Kotlin编程相关知识点介绍


高阶函数


A higher-order function is a function that takes functions as parameters, or returns a function

高阶函数具备以下特征:

  • 接受一个函数作为参数
  • 或者返回一个函数

为List扩展一个函数,使用高阶函数用法,编写代码如下:

package com.xingen.kotlin.day201761

fun main(args: Array<String>) {

    var oldlist = arrayListOf<Int>(1, 2, 3)
    println("原本数据是 $oldlist")

    /**
     *  面向函数:类似Java8中lambda表达式,传入一个函数对象。
     *  lambda表达式的形式: { 参数名 -> 函数体 }
     *  这里的item是参数,返回值item+3是函数体
     *
     *  注意点:List.transform()是带有括号的,
     *  但是在Kotlin编程中方法最后一个参数是函数,且传入lambda表达式作为参数的话,函数的括号可以省略,
     *  因此,是这里是List.transform{ lambda表达式 }
     */

    var newList = oldlist.transform { item -> item + 3 }
    println("转换后的新数据是 $newList")
}

/**
 * 给List 类定义一个扩展函数transform() ,
 * 然后使用高阶函数,其中方法参数是一个函数
 */
fun <T, R> List<T>.transform(transformFun: (T) -> R): List<R> {
    //创建一个新的List对象,用于装载转换后的item
    var result = arrayListOf<R>()
    /**
     * 类似java中增强for循环。
     * 扩展函数中的this指向接受者对象,也就是该调用扩展函数的对象
     */
    for (item in this) {
        var newItem = transformFun(item)// 调用参数中的函数方法进行转换新的item.
        result.add(newItem)
    }
    return result
}

输出结果:

原本数据是 [1, 2, 3]
转换后的新数据是 [4, 5, 6]

可知:

  • lambda表达式的形式:{ 参数名 -> 函数体 }

  • 但是在Kotlin编程中方法最后一个参数是函数,且使用lambda表达式作为参数传入,方法的括号可以省略。例如,上面的代码:List.transform{ lambda表达式 }

Lambda表达式


一个Lambda表达式是一个字面函数,即一个未声明的函数,会以表达式的形式传递。

 oldlist.transform { item -> item + 3 }

上面的Lambda表达式,实际上也是一个字面函数,等同于以下函数:

fun <T> transformFun(item: T):T{
    return item+3
}

函数类型

接收一个函数作为参数,为参数指定函数类型。例如:

fun <T, R> List<T>.transform(transformFun: (T) -> R): List<R> {
    //创建一个新的List对象,用于装载转换后的item
    var result = arrayListOf<R>()
    /**
     * 类似java中增强for循环。
     * 扩展函数中的this指向接受者对象,也就是该调用扩展函数的对象
     */
    for (item in this) {
        var newItem = transformFun(item)// 调用参数中的函数方法进行转换新的item.
        result.add(newItem)
    }
    return result
}

参数transformFun的类型是(T) -> R,解读函数类型的意思:传递一个参数,返回一个相同类型的返回值。

transformFun参数是一个函数,因此作为一个函数来使用,传递一个T类型的参数,会返回同类型的返回值。

Lambda表达式语法

第一种语法:

/**
 * 一个完成的Lambda表达式
 */
var total1={x:Int,y:Int->x+y}

第二种,含可选标注的语法

/**
 * 带有可选标注的Lambda表达式,使文档化每个参数的含义
 * 
 * var total2:(Int,Int)->Int=...这种函数类型,可理解为一个函数中接受一个函数做为参数时候,参数的声明形式。
 */
var total2:(Int,Int)->Int={  x,y   ->   x+y   }

在Main函数中调用:

package com.xingen.kotlin.day201761

fun main(args: Array<String>) {

    println(  total1(1,2)  )
    println(total2(1,2))
}

输出结果如下:

3
3

可知:

  • lambda 表达式总是被大括号括着, 完整语法形式的参数声明放在括号内,并有可选的类型标注, 函数体跟在一个 -> 符号之后。

  • 如果推断出的该 lambda 的返回类型不是 Unit,那么该 lambda 主体中的最后一个(或可能是单个)表达式会视为返回值

匿名函数


大多数情况下,Lambda表达式是不指定函数的返回类型,因为可以自动推断出来。当需要显式指定函数的返回类型,需要使用到:匿名函数

编写一个匿名函数的案例:

package com.xingen.kotlin.day201761

fun main(args: Array<String>) {

    println(test3(1,2))
    println(test4(1,2))
    println(test5(1,2))
}

/**
 * 匿名函数,没有名字,其他语法和常规函数类似
 *
 * 声明一个匿名函数,这里用表达式来表示函数体
 */
var test3= fun(x:Int,y:Int):Int=x+y
/**
 * 声明一个匿名函数,这里用代码块来表示函数体
 */
var test4= fun(x:Int,y:Int):Int{
    return  x+y
}
/**
 * 声明一个匿名函数,当返回值类型可以推断出,可以省略
 */
var test5= fun(x:Int,y:Int)=x+y

输出结果如下:

3
3
3

可知:

  • 匿名函数,没有名字,其他语法和常规函数类似,例如:当返回值类型可以推断出,可以省略

除了以上提到的显式指定函数的返回类型区别外,Lambda表达式和匿名函数的另外一个区别:

一个不带标签的 return 语句 总是在用 fun 关键字声明的函数中返回。这意味着 lambda 表达式中的 return 将从包含它的函数返回,而匿名函数中的 return 将从匿名函数自身返回。

闭包


闭包是指在外部作用域中声明的变量。与Java不同的是,在Kotlin编程中,可以修改闭包中捕获的变量。

可以访问闭包的:

  • Lambda表达式
  • 匿名函数
  • 局部函数(函数内包含函数)
  • 对象表达式

例如,案例:

package com.xingen.kotlin.day201761

fun main(args: Array<String>) {

    println(i)
    test4(1,2)
    println(1)
}
var i=0
/**
 * 声明一个匿名函数,这里用代码块来表示函数体
 */
var test4= fun(x:Int,y:Int):Int{
    i++ //外部的变量,且修改
    return  x+y
}

输出结果:

0
1

带有接受者的字面函数


Kotlin 提供了使用指定的 接收者对象 调用函数字面值的功能。 在函数字面值的函数体中,可以调用该接收者对象上的方法而无需任何额外的限定符。 这类似于扩展函数,它允你在函数体内访问接收者对象的成员。

package com.xingen.kotlin.day201761

fun main(args: Array<String>) {

    //类似扩展函数的用法,用实例对象来调用
    println( 1.test6(2) )
    println( 1.test7(2) )
}
/***
 * 带有接受者的Lambda表达式
 *
 * 这里的函数类型是一个带有接受者的类型:
 *
 * test6:Int.(other:Int)->Int
 */
var test6:Int.(other:Int)->Int={ other->other+1}
/**
 * 带有接受者的匿名函数
 *
 * 用表达式表达式函数体:
 *
 * var test7=fun Int.(other:Int):Int=this+other
 *
 * 这里, 用代码块表示函数体,来声明一个匿名函数,最后赋给一个变量
 */
var test7=fun Int.(other:Int):Int{
    return this+other   //this是指向接受者的对象
}

输出结果如下:

3
3
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值