Kotlin 基础学习笔记第八章——高阶函数:Lambda作为形参和返回值

news2024/11/17 15:54:38

一、声明高阶函数

        高阶函数定义:高阶函数就是以另一个函数作为参数或者返回值的函数 在kotlin中,函数可以用lambda或者函数引用来表示。因此,任何以lambda或者函数引用作为参数的函数,或者返回值为lamda或函数应用的函数,或者两者都满足的函数都是高阶函数。

        1、函数类型

        为了声明一个以lamda作为实参的函数,你需要知道如何声明对应形参的类型。在这之前,我们先来看一个简单的例子,把lambda表达式保存在局部变量中。其实我们已经见过在不声明类型的情况下如何做到这一点,这依赖于kotlin的类型推导。 

        在这个例子中,编译器推导出sum和action这两个变量具有函数类型。现在我们来看看这些变量的显式类型声明是什么样的:

        声明函数类型,需要将函数参数类型放在括号中,紧接着是一个箭头函数的返回类型。 

         你应该还记得,Unit类型用于表示函数不返回任何有用的值声明一个普通的函数时,Unit类型的值是可以省略的,但是一个函数类型声明总是需要一个显式的返回类型,所以在这种场景下Unit是不能省略的

        注意,在lambda表达式{x, y -> x + y}中是如何省略参数x, y的类型的。因为它们的类型已经在函数类型的变量声明部分指定了,不需要在lamda本身的定义当中再重复声明

        就像其他方法一样,函数类型的返回值也可以标记为可空类型        

        也可以定义一个函数类型的可空变量为了明确表示是变量本身可空,而不是函数类型的返回类型可空,你需要将整个函数类型的定义包含在括号内并在括号后面添加一个问号

        注意这个例子和前一个例子的微妙区别。如果省略了括号,声明的将会是一个返回值可空的函数类型,而不是一个可空的函数的变量         

        2、调用作为参数的函数

        知道了怎样声明一个高阶函数,现在我们来讨论如何去实现它。

        调用作为参数的函数和调用普通函数的语法是一样的:把括号放在函数名后,并把参数放在口号内。

        来看一个更有趣的例子,我们来实现最常用的标准库函数:filter函数。为了让事情简单一点,将实现基于String类型的filter函数,但和作用于集合的泛型版本的原理是相似的。函数声明如下:

         filter函数以一个判断式作为参数。判断式的类型是一个函数,以字符作为参数并返回boolean类型的值。如果要让传递给判断式的字符出现在最终返回的字符串中,判断式需要返回true,反之返回false。下面是具体实现:

        filter函数的实现非常明了。它检查每个字符是否满足判断式,如果满足就将字符添加到包含结果的StringBuilder中。

        3、在java中使用函数类

         其背后的原理是,函数类型被声明为普通的接口:一个函数类型的变量是FunctionN接口的一个实现。kotlin标准库定义了一系列的接口,这些接口对应于不同参数数量的函数:Function0<R>(没有参数的函数),Function1<P1,R>(一个参数的函数),等待。每个接口定义了一个invoke方法,调用这个方法就会执行函数。一个函数类型的变量就是实现了对应的FunctionN接口的实现类的实例,实现类的invoke方法包含了lambda函数体

        在java中可以很简单地调用函数类型的kotlin函数。java8的lambda会被自动转换为函数类型的值。

         在java中可以很容易地使用kotlin中以lambda作为参数的扩展函数。但是要注意他们看起来并没有kotlin中那么直观——必须要显示地传递一个接收者对象作为第一个参数

         在java中,函数或者lambda可以返回Unit。但因为在kotlin中Unit类型是有一个值的,所以需要显式地返回它。一个返回返回void的lambda不能作为返回Unit的函数类型的实参,就像之前的例子中(String)-> Unit。

        4、函数类型的参数默认值和null值

        声明函数类型的参数的时候可以指定参数的默认值。要知道默认值的用处,我们回头看下第三章讨论的joinToString函数。

         注意这是一个泛型函数:它有一个类型参数T表示集合中的元素的类型。Lambda transform函数将接受这个类型的参数。

        声明函数类型的默认值并不需要特殊的语法——只需要把lambda作为值放在=号后面。 上面的例子展示了不同的函数调用方式省略整个lambda(使用默认的toString()做转换),在括号以外传递lambda,或者以命名参数形式传递

        另一种选择是声明一个参数为可空的函数类型。注意这里不能直接调用作为参数传递进来的函数:kotlin会因为检测到潜在的空指针异常而导致编译失败。一种可选的方法时显式地检查null。

        还有一个更简单的版本,它利用了这样一个事实,函数类型是一个包含invoke方法的接口的具体实现。作为一个普通方法,invoke可以通过安全调用语法被调用:callback?.invoke()。

        下面介绍使用这项技术重写joinToString函数。

        现在你已经知道了如何编写接收另外的函数作为参数的函数。

        5、返回函数的函数 

        

         

                              

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/78086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于遗传算法优化的lssvm回归预测-附代码

基于遗传算法优化的lssvm回归预测 - 附代码 文章目录基于遗传算法优化的lssvm回归预测 - 附代码1.数据集2.lssvm模型3.基于遗传算法优化的LSSVM4.测试结果5.Matlab代码摘要&#xff1a;为了提高最小二乘支持向量机&#xff08;lssvm&#xff09;的回归预测准确率&#xff0c;对…

使用openshift 进行云平台连接

使用openshift 进行云平台连接 OpenShift CLI on Windows openshift 文档地址 OpenShift CLI on Mac 通过Homebrew方式安装 brew install openshift-cli安装完成&#xff0c;进行验证 oc version服务连接 oc login 服务地址根据提示输入用户名和密码&#xff0c;即可连接…

某讯滑块验证码反汇编分析-第一章

某讯滑块验证码反汇编分析-第一章js分析初步分析vmp结构js分析 在滑动完成后&#xff0c;会请求【cap_union_new_verify】接口&#xff0c;其中有5个比较长的参数&#xff0c;看起来可能会有加密的&#xff0c;分别如下。 参数名来源uasesscollecteksvData 那现在js看看这些参…

让车机「下雨」,路特斯的智能座舱跑偏了吗?

HIEV消息&#xff08;文/张祥威&#xff09;“我们今天用双8155&#xff0c;都觉得&#xff08;算力&#xff09;还不够。”杨平说。 这位路特斯的智能座舱研发负责人&#xff0c;目前带领着一支两百多人的团队&#xff0c;为Eletre这款车操刀座舱智能化。 双8155&#xff0c;指…

Gitee应用(1):快速搭建Git环境在不同电脑同步文件

一、前言 环境&#xff1a;Windows 11 64位 &#xff1b;vscode&#xff1a;1.73.1 当你要操作在两台不同的电脑上操作&#xff0c;或许经常会遇到一个问题&#xff0c;就是怎么同步同一个或几个文件&#xff0c;以方便你在不同的电脑上进行同个文件内容的创作。 在申请了公司电…

【Java难点攻克】「NIO和内存映射性能提升系列」彻底透析NIO底层的内存映射机制原理与Direct Memory的关系

NIO与内存映射文件 Java类库中的NIO包相对于IO包来说有一个新功能就是 【内存映射文件】&#xff0c;在业务层面的日常开发过程中并不是经常会使用&#xff0c;但是一旦在处理大文件时是比较理想的提高效率的手段&#xff0c;之前已经在基于API和开发实战角度介绍了相关的大文…

Java Math类

JavaMath类\huge{Java \space Math类}Java Math类 Math类 包含执行基本数字运算的方法&#xff0c;Math类没有提供公开的构造器。 MathMathMath类本质就是一个工具类&#xff0c;提供许多方法用于其他类调用&#xff0c;但是无法创建子类对象。 常用方法 ①. abs()取绝对值…

CANoe测试的两种方式Test Module 和 Test Unit对比,你常用哪种呢?

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

前端接口联调时传的参数是array数组形式处理

情景&#xff1a;使用van-uolaoder组件上传多个图片后调用保存按钮&#xff0c;这时由于存在多张图片&#xff0c;调用接口时前端传的参数就是数组形式。&#xff08;前端传的数组要先转为字符串&#xff09; 处理方法是&#xff1a; 1. 先确定后端使用什么注解&#xff0c;如…

Gerb视图支持新表单和旧表单

Gerb视图支持新表单和旧表单 GerbView生产高级软件Companions&#xff0c;但也易于替换、打印和查看HPGL、HPGL/2、Excellon和国际象棋文件。该程序支持RS274D和RS274X。您可以使用此软件将旧格式和标准RS274D转换为具有默认信息的新类型RS274X。Gerbview将致力于展示和绘制您的…

计算机毕业设计django基于python租房系统-房屋租赁系统

项目介绍 在各学校的教学过程中,租房系统是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及。采用当前流行的B/S模式以及3层架构的设计思想通过Python技术来开发此系统的目的是建立一个配合网络环境的租房系统的平台,这样可以有效地解决租房系统混乱的局面。 本文…

(P3)python类的特殊方法 init、getitem、len、call

python 类的特殊方法 参考资料 python解释器遇到特殊句法时&#xff0c;会去调用特殊方法&#xff0c;这些特殊方法以双下划线开头。 1、__init __ () 该方法在对象创建时被解释器自动调用。 2、__getitem __ () getitem 获取实例对象的具体内容 p[key] 3、__len __() len …

牛客挑战赛65 D.233求min(二维偏序 树状数组/cdq分治)

题目 给出长度为n(n<1e5)的序列a1,a2,...,an​和b1,b2,...,bn(-1e3<ai,bi<1e3)&#xff0c; 请你找出1≤l≤r≤n&#xff0c;使得min(alal1...ar, blbl1...br)最大&#xff0c;并输出这个值 思路来源 官方题解 LYC_music submission 题解 两种做法&#xff0c; …

Python模块和包的介绍(模块含义、用模块好处、模块分类、包和模块的创建)

&#x1f308; 个人主页&#xff1a;王子玉博客 &#x1f506; 免费专栏&#xff1a;Python基础教程、python常用模块 ❤️ 分享网站&#xff1a; 《Python自学网》&#x1f449;&#x1f449;基础入门到逐步深入 | 适合新手入门到精通 | web开发、爬虫、自动化运维、自动化…

yocto 自动挂载分区(基于stmp32mp1)

yocto 自动挂载分区&#xff08;基于stmp32mp1&#xff09; 上一章我们在stm32mp1开发板上实践了创建分区的过程&#xff0c;本节我们再来分析下上小节创建的分区开机时是怎么完成分区的自动挂载的。 答案就在systemd里面&#xff1a; 下面就来详细分析一下这个几个文件 mo…

C/C++入门003-C语言变量与运算符

文章目录变量常量的概念常量的类型变量的概念定义变量为什么要定义变量如何使用变量&#xff1f;变量初始化修改变量变量之间的值传递如何查看变量的值?变量的作用域printf函数scanf函数函数的参数运算符算数运算符赋值运算符sizeof运算符逗号运算符关系运算符逻辑运算符三目运…

攻击类型的攻击次数分布

攻击类型分析 2018 年&#xff0c;主要的攻击类型 1 为 SYN Flood&#xff0c;UDP Flood&#xff0c;ACK Flood&#xff0c;HTTP Flood&#xff0c;HTTPS Flood&#xff0c; 这五大类攻击占了总攻击次数的 96&#xff05;&#xff0c;反射类攻击不足 3%。和 2017 年相比&…

【Linux网络编程】select多路复用

文章目录前言如何增强服务端的通信能力Linux的设计哲学文件描述符代码讲解以文件方式操作命令行阻塞函数与非阻塞函数轮询select()代码全貌The End前言 我们上节课讲解了服务端的编程(Linux服务端编程初体验) 本节课要讲的是select 提示&#xff1a;以下是本篇文章正文内容&am…

RocketMQ引发的磁盘预警复盘

RocketMQ引发的磁盘预警复盘前言发现问题排查过程Step 1Step 2Step 3Step 4Step 5Step 6Step 7Step 8Step 9解决方式写在最后前言 一款优秀的中间件&#xff0c;参数的缺省值必然是经过反复验证得出的最优解&#xff0c;勿动&#xff01; 发现问题 某台SaaS服务器磁盘不足发出…

kafka的 __consumer_offsets

Zookeeper不适合大批量的频繁写入操作。Kafka 1.0.2将consumer的位移信息保存在Kafka内部的topic中&#xff0c;即__consumer_offsets主题&#xff0c;并且默认提供了kafka_consumer_groups.sh脚本供用户查看consumer信息。 1、创建topic “tp_test_01” [rootnode1 ~]# kafka…