当前位置: 首页 > news >正文

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的平台上运行,而无需重新编译。…...

idea大量爆红问题解决

问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...