Jetpack:009-kotlin中的lambda、匿名函数和闭包
文章目录
- 1. 概念介绍
- 2. 使用方法
- 2.1 函数类型的变量
- 2.2 高阶函数
- 3. 内容总结
- 4.经验分享
我们在上一章回中介绍了Jetpack中Icon和Imamg相关的内容,本章回中主要介绍Kotlin中的
lambda、匿名函数和闭包。闲话休提,让我们一起Talk Android Jetpack吧!
1. 概念介绍
关于lambda的概念比较抽象,我们通过它的特征来描述它的概念:由花括号包裹并且有箭头特征的表达式就是lambda,花括号是整个lambda的内容,箭头前的内容是它的参数,箭头后的内容是它的实现内容。
和lambda比较类似是的匿名函数和闭包,匿名函数就是没有函数名的函数,lambda也没有名称,因此它们十分相似,只有在函数有返回值的时候它们才不同:匿名函数有明确的return语句,而lambda表达式没有明确的返回语句,它通常把实现内容中最后一个表达式的值当作返回值。
闭包比较好理解:位于花括号中的内容就是闭包。虽然lambda也位于花括号内,但是它只是闭包的一部分,闭包中包含的内容不只是lambda,因此可以把lamdba看作是闭包的子集。
明白这些概念后,我们通过具体的代码来演示它的使用方法。
2. 使用方法
2.1 函数类型的变量
//变量类型是函数,使用匿名函数来赋值
var funValue:()->String = fun():String{return "this is a function"}
//变量类型是函数,使用lambda来赋值
var funValue0:()->String = {"this is a function"}
//变量类型是函数,使用匿名函数来赋值,省略变量类型
var funValue1 = fun():String { return "this is a function"}
//变量类型是函数,使用lambda赋值,省略变量类型
var funValue11 = {"this is a function"}
//只有一行语句时花括号也可以省略
var funValue111 = "this is a function"
上面的示例代码中,我们定义了变量funValueXXX(为了区分不同的变量名称在尾部添加了多个数字),它的类型是函数类型,我们先使用匿名函数给它赋值,然后再使用lambda表达式给它赋值,这样可以区分开匿名函数和lambda表达式的差异。
从代码中可以看到匿名函数的特点:有关键字fun和return.相比之下lambda就可以省略这些关键字,甚至连大括号也可以省略。接下来我再演示一个复杂一些函数类型。
//变量类型是函数,函数有参数,但是无返回值,使用匿名函数来赋值,这做做法也叫类型实例化
var funValue2:(values:Int)->Unit =fun (values:Int){ "this is a function,param:$values"}
//变量类型是函数,函数有参数,但是无返回值,使用匿lambda来赋值,这做做法也叫类型实例化
var funValue21:(values:Int)->Unit ={values -> "this is a function,param:$values"}
//变量类型是函数,函数有参数和返回值,使用匿名函数来赋值
var funValue31:(values:Int)->String = fun(values):String {return "this is a function,param:$values"}
//变量类型是函数,函数有参数和返回值,使用lambda来赋值
var funValue32:(values:Int)->String ={values -> "this is a function,param:$values"}
//变量类型是函数,使用lambda来赋值,省略了参数,只有一个参数时使用it代替参数,it是单个参数的隐式名称
var funValue33:(values:Int)->String ={ "this is a function,param:$it"}
上面的示例代码中,我们定义了变量funValueXXX(为了区分不同的变量名称在尾部添加了多个数字),它的类型是函数类型,这个函数带有参数,而且分有返回值和无返回值的两种情况。我们先使用匿名函数给它赋值,然后再使用lambda表达式给它赋值,这样可以区分开匿名函数和lambda表达式的差异。
从代码中可以看到当函数类型中包含返回值时匿名函数的内容比lambda多,lambda显得相对简洁一些。当函数类型中带有参数时lambda表达式显得更加简洁。
看了这么多示例,可以得出lambda表达式最大的特征就是有箭头。此外,lambda表达式还有一个语法就是省略参数,使用it来代替参数。这个语法在compose中经常使用。
2.2 高阶函数
高阶函数就是函数的参数或者返回值的类型是其它函数,相当于把函数当作变量传递给高阶函数的参数或者当作高阶函数的返回值。下面是我们通过示例代码来演示:
//高阶函数:函数的参数或者返回值是其它的函数,相当把函数当作数值来使用
fun inFun(name:String,age: Int):String {return name+age
}
//只有一行语句时可以省略大括号和return
fun inFun1(name:String,age: Int):String = name+age
//返回类型可以通过类型推导出来,也可以省略
fun inFun2(name:String,age: Int) = name+age//函数的第二个参数是函数类型
fun outFun(id:Int,type:(s:String,a:Int)->String):String {val age = (1..10).random()println(inFun("Sam ",age))println("id: $id, type: $type")return "age = $age"
}//通过函数引用把命名函数(具名函数)inFun1当作参数传递给outFun函数
var res = outFun(3, ::inFun1)
//把匿名函数当作参数传递给outFun函数,注意关键字fun不能省略
var res1 = outFun(33,fun(s:String,a:Int):String{return "str = $s ,$a"})//使用lambda表达式代替匿名函数,把lambda表达式传递给outFun函数
//注意lambda必须使用花括号包起来,箭头前是参数,箭头后是函数体
//注意匿名函数的return不能省略,lambda的可以省略,而且通常是最后一个表达式的值
var res2= outFun(33,{s:String,a:Int->"str = $s ,$a"})
//省略lambda表达式中的参数类型,返回类型,return关键字
var res3= outFun(33,{s,a->"str = $s ,$a"})
//函数的最后一参数是lambda时可以将其移动到括号外面(这叫尾lambda)
var res4= outFun(33){s,a->"str = $s ,$a"}
上面的示例代码中包含高阶函数,该函数的参数是函数类型,从示例代码中可以看到使用lambda表达式传递参数比匿名函数传递参数的代码要简洁一些。代码中介绍了函数的两种语法:
- 通过等号来实现简单函数体,进而省花括号和return关键字;
- 通过函数引用(两个冒号)来传递命名函数给高阶函数;
代码中还介绍一种尾lambda的语法:当lambda是高阶函数的最后一个参数时,可以将它移动到高阶函数的外面,也就是花括号中。这个语法在compose中十分常见。
3. 内容总结
最后,我们对本章回中的内容做一个总结:
- lambda和匿名函数十分类似,它们都可以用来给函数类型的变量赋值,或者和高阶函数一起使用;
- 与lambda表达式类似还有闭包,它的范围比较广,lambda只是它的一个子集;
- 匿名函数的特征就是没有函数名,但是有fun和return关键字;
- lambda表达式的特征就是有箭头和花括号;
- 在大部分场景下lambda的语法更加简洁;
4.经验分享
关于lambda表达式和匿名函数的语法,大家普通的反应就是看不懂代码。这就是代码简洁与代码易懂之间的茅盾,我在开始看这类代码时也有同样的感觉,我的经验就是:尽量让代码保持简洁,如果感觉读不懂代码,那么多动手练习一下就可以掌握这种难理解的语法。比如,上面的示例代码都是我自己对匿名函数和lambda表达式的理解,多写一些就会明白其中的原理,到时候就能读懂代码了。
此外,还有一些特殊的语法,只能是硬记语法规则,这个没有任何窍门,好在特殊内容比较少,比如前面小节中介绍的尾lambda和it。
我最开始看这类代码是在Java中,还记得给Button添加监听器(setOnClickListener)就是使用匿名函数,刚开始不理解,但是写多了就养成了习惯,反而觉得这种写法十分方便。我把这个学习经验从Java迁移到了Kotlin中,在此分享给大家,希望对大家有帮助。
看官们,关于Kotlin中的lambda、匿名函数和闭包就介绍到这里,欢迎大家在评论区交流与讨论!
相关文章:
Jetpack:009-kotlin中的lambda、匿名函数和闭包
文章目录 1. 概念介绍2. 使用方法2.1 函数类型的变量2.2 高阶函数 3. 内容总结4.经验分享 我们在上一章回中介绍了Jetpack中Icon和Imamg相关的内容,本章回中主要介绍Kotlin中的 lambda、匿名函数和闭包。闲话休提,让我们一起Talk Android Jetpack吧&…...
openGauss指定schema下全部表结构备份与恢复
本次测试针对openGauss版本为2.0.5 gs_dump指定schema下全部表结构信息备份 gs_dump database_name -U username -p port -F c -s -n schema_name -f schema.sqldatabase_name:数据库名,要备份的数据库名称 username:用户名,数据…...
干货:如何在前端统计用户访问来源?
在前端统计用户访问来源是一个常见的需求,通过获取访问来源信息,我们可以了解用户是通过直接访问、搜索引擎、外部链接等途径进入我们的网站或应用。下面是一个详细的介绍,包括方法和实现步骤。 一、获取HTTP Referer HTTP Referer是HTTP请…...
李宏毅生成式AI课程笔记(持续更新
01 ChatGPT在做的事情 02 预训练(Pre-train) ChatGPT G-Generative P-Pre-trained T-Transformer GPT3 ----> InstructGPT(经过预训练的GPT3) 生成式学习的两种策略 我们在使用ChatGPT的时候会注意到,网站上…...
nodejs+vue+elementui酒店客房服务系统mysql带商家
视图层其实质就是vue页面,通过编写vue页面从而展示在浏览器中,编写完成的vue页面要能够和控制器类进行交互,从而使得用户在点击网页进行操作时能够正常。 简单的说 Node.js 就是运行在服务端的 JavaScript。 前端技术:nodejsvueel…...
【网络协议】聊聊网络分层
常用的网络协议 首先我们输入www.taobao.com,会先经过DNS进行域名解析,转换为59.82.122.115的公网IP地址。然后就会发起请求,一般来说非加密的使用http,加密的使用https。上面是在应用层做的处理,那么接下来就是到传输…...
[开源]基于Vue+ElementUI+G2Plot+Echarts的仪表盘设计器
一、开源项目简介 基于SpringBoot、MyBatisPlus、ElementUI、G2Plot、Echarts等技术栈的仪表盘设计器,具备仪表盘目录管理、仪表盘设计、仪表盘预览能力,支持MySQL、Oracle、PostgreSQL、MSSQL、JSON等数据集接入,对于复杂数据处理还可以使用…...
html设置前端加载动画
主体思路参考: 前端实现页面加载动画_边城仔的博客-CSDN博客 JS图片显示与隐藏案例_js控制图片显示隐藏-CSDN博客 1、编写load.css /* 显示加载场景 */ .loadBackGround{position: absolute;top: 0px;text-align: center;width: 100%;height: 100vh;background-c…...
【git的使用方法】——上传文件到gitlab仓库
先进入到你克隆下来的仓库的目录里面 比如:我的仓库名字为zhuox 然后将需要上传推送的文件拷贝到你的克隆仓库下 这里的话我需要拷贝的项目是t3 输入命令ls,就可以查看该文件目录下的所有文件信息 然后输入git add 文件名 我这边输入的是 &#x…...
Kafka 开启SASL/SCRAM认证 及 ACL授权(二)ACL
Kafka 开启SASL/SCRAM认证 及 ACL授权(二)ACL。 官网地址:https://kafka.apache.org/ kafka authentorization:https://docs.confluent.io/platform/current/kafka/authorization.html 一、开启ZK ACL(可选,内网环境,用户无机器访问权限时) 给kafka meta都加上zk的ac…...
Java8 新特性之Stream(三)-- Stream的终结操作
目录 1.forEach(Consumer) 2.reduce(BinaryOperator) 3.max([Comparator]) 4.min([Comparator]) 5.count() 6.findFirst() 7.findAny() 拓展:...
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:vue要做权限管理该怎么做…...
1、验证1101序列(Moore)
题目要求: 用Moore型状态机验证1101序列。 题目描述: 用使用状态机验证1101序列,注意:允许重复子序列。如图 端口描述: module moore_1101(input clk,//时钟信号input clr,//reset复位信号,高电平有效in…...
Java基础面试-BeanFactroy和ApplicationContext
ApplicationContext是BeanFactory的子接口 ApplicationContext提供了更完整的功能: 继承MessageSource,因此支持国际化。统一的资源文件访问方式。提供在监听器中注册bean的事件。同时加载多个配置文件。载入多个(有继承关系)上下文,使得每一个上下文都…...
js的入口函数
JavaScript的入口函数是指在HTML页面加载完毕后,JavaScript代码开始执行的函数。这个函数一般被称为onload函数,它的作用是在页面加载完成后执行一些初始化操作,或者对页面进行动态修改。 在HTML页面中,可以通过以下方式设置入口…...
[cpp primer随笔] 10. 函数重载与重载决议
本篇将介绍C函数重载的概念,及重载决议规则。 一、函数重载 同一作用域内,函数名相同,而形参列表不同的函数称之为重载函数(overloaded function)。 需要特别注意:以下情况看似形参列表不同,实则等价,无法…...
java_Stream API
文章目录 一、Stream API vs 集合二、Stream 使用的执行流程2.1、创建Stream2.1、中间操作2.1.1. filter2.1.2. limit2.1.3. skip2.1.4. distinct2.1.5. map2.1.6. sorted 一、Stream API vs 集合 Stream API 关注的是多个数据的计算(排序、查找、过滤、映射、遍历…...
红队专题-工具Fscan
红队专题 招募六边形战士队员简介主要功能 ubuntu 安装windows 安装常用命令:项目框架源文件common目录Plugins目录Webscan目录爆破插件common.Scantype Webtitle函数webpoc扫描类型指纹识别 免杀源码特征 参考链接 招募六边形战士队员 一起学习 代码审计、安全开发…...
【宏实现二进制奇偶位交换】
文章目录 一. 二进制奇偶位交换说明意思?二. 解题思路三. 代码验证四. 总结 一. 二进制奇偶位交换说明意思? 就是一个int类型的整数在操作系统下是32位二进制01序列,第一位和第二位交换,第二位和第三位交换,依次类推。…...
【Java零基础入门到就业】第一天:java简介和cmd窗口的一些常见命令
1、java简介 Java是一种基于类的、面向对象的编程语言,它被设计成具有尽可能少的实现依赖。它旨在让应用程序开发人员编写一次,并在任何地方运行(WORA),这意味着编译后的Java代码可以在所有支持Java的平台上运行,而无需重新编译。…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
