Android Kotlin之let、with、run、apply、also函数的使用
前言
一、Kotin的lambda
二、let函数
三、with函数
四、 run函数
五、 apply函数
六、 also函数
七、总
前言
相比Java语言Kotlin更加简洁安全高效。不仅支持lambda表达式,还支持非空验证机制,另外提供一套源码标准库(Standard.kt)。但是,对于Kotlin的初学者来说,可能会经常写编写出不够优雅的代码,而Kotlin提供了一些内置函数便可以帮助优化代码。
Standard.kt是Kotlin库的一部分,它定义了一些基本函数。 这个源代码文件虽然一共不到50行代码,但是这些函数功能都非常强大。
一、Kotin的lambda
在Kotlin中对Java中的一些的接口的回调可以使用一个lambda函数做一些优化,减少一些不必要的嵌套回调方法。
但是需要注意lambda表达式的规则,只支持单抽象方法模型,不支持多个回调方法。
1、Java代码接口的回调
mView.setEventListener(new ExamPlanHomeEventListener(){public void onSuccess(Data data){//TODO}});
2、Kotlin实现接口的回调
mView.setEventListener(object: ExamPlanHomeEventListener{public void onSuccess(Data data){//TODO}
});mView.setEventListener({data: Data ->//TODO
})//或者可以直接省略Data,借助kotlin的智能类型推导
mView.setEventListener({data ->//TODO
})//如果以上代码中的data参数没有使用到的话,可以直接把data去掉
mView.setEventListener({//TODO
})
//或
mView.setEventListener(){//TODO
}
//只有一个参数,可以直接省略圆括号
mView.setEventListener{//todo
}
可见十分的简洁。
二、let函数
1、简介
let函数实际上是一个作用域函数,当需要去定义一个变量在一个特定的作用域范围内时,就可以使用let函数。let函数只接收一个 Lambda 参数,并且会在 Lambda 函数块中提供调用对象的上下文。let函数另一个作用就是可以避免写一些判断null的操作。
2、示例
//在函数体内使用it替代object对象去访问其公有的属性和方法
object.let{it.todo()...
}//另一种用途 判断object为null的操作
object?.let{it.todo()//表示object不为null的条件下,才会去执行let函数体
}
//使用let前
mVideoPlayer?.setVideoView(activity.course_video_view)
mVideoPlayer?.setControllerView(activity.course_video_controller_view)
mVideoPlayer?.setCurtainView(activity.course_video_curtain_view)//使用let后
mVideoPlayer?.let {it.setVideoView(activity.course_video_view)it.setControllerView(activity.course_video_controller_view)it.setCurtainView(activity.course_video_curtain_view)
}
3、分析
从源码let函数的结构来看它是只有一个lambda函数块block作为参数的函数。调用T类型对象的let函数,则该对象为函数的参数。在函数块内可以通过 it 指代该对象。返回值为函数块的最后一行或指定return表达式。
4、使用场景
场景一: 最常用于使用let函数处理需要针对一个可null的对象统一做判空处理。
场景二: 需要去明确一个变量所处特定的作用域范围内。
三、with函数
1、 简介
with函数用于对同一个对象执行多次操作而不需要反复把对象的名称写出来,在代码中,with 可以理解为“对于 ”这个对象执⾏以下操作。
with函数接收两个参数:第一个参数可以是一个任意类型的对象T,第二个参数是一个 Lambda 函数块。 with 函数会在 Lambda 函数块中提供第一个参数对象的上下文。
2、 示例代码
with(object){//todo}//源码
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
使用with前
@Override
public void onBindViewHolder(ViewHolder holder, int position) {ArticleSnippet item = getItem(position);if (item == null) {return;}holder.tvNewsTitle.setText(StringUtils.trimToEmpty(item.titleEn));holder.tvNewsSummary.setText(StringUtils.trimToEmpty(item.summary));String gradeInfo = "难度:" + item.gradeInfo;String wordCount = "单词数:" + item.length;String reviewNum = "读后感:" + item.numReviews;String extraInfo = gradeInfo + " | " + wordCount + " | " + reviewNum;holder.tvExtraInfo.setText(extraInfo);...
}
使用with后
override fun onBindViewHolder(holder: ViewHolder, position: Int){val item = getItem(position)?: returnwith(item){holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)holder.tvExtraInf.text = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"}
}
3、分析
with函数和前面的几个函数使用方式略有不同,因为它不是以扩展的形式存在的。它是将某对象作为函数的参数,在函数块内可以通过 this 指代该对象。返回值为函数块的最后一行或指定return表达式。
4、场景
适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可,经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上。
四、 run函数
1、 简介
run函数实际上可以说是let和with函数两个函数的结合体。run 函数只接收一个 Lambda 参数,并且会在 Lambda 函数块中提供调用对象的上下文。
2、 示例代码
object.run{
//todo
}
//源码
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R = block()
使用run前
override fun onBindViewHolder(holder: ViewHolder, position: Int){val item = getItem(position)?: return with(item){ holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)holder.tvExtraInf = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"}
}
使用run后
override fun onBindViewHolder(holder: ViewHolder, position: Int){ getItem(position)?.run{holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)holder.tvExtraInf = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"}
}
3、分析
run函数实际上可以说是let和with两个函数的结合体,run函数只接收一个lambda函数为参数,以闭包形式返回,返回值为最后一行的值或者指定的return的表达式。
4、场景
适用于let、with函数任何场景。因为run函数是let,with两个函数结合体,准确来说它弥补了let函数在函数体内必须使用it参数替代对象,在run函数中可以像with函数一样可以省略,直接访问实例的公有属性和方法,另一方面它弥补了with函数传入对象判空问题,在run函数中可以像let函数一样做判空处理。
五、 apply函数
1、简介
apply 函数和 run 函数也是极其类似的,都要在某个对象上调用,并且只接收一个 Lambda 参数,也会在 Lambda 函数块中提供调用对象的上下文。但是 apply 函数无法指定返回值,而是会自动返回调用的对象本身。
2、示例代码
object.apply{
//todo
}//源码
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
使用apply前
if (mSectionMetaData == null || mSectionMetaData.questionnaire == null || mSectionMetaData.section == null) {//todoreturn;
}
if (mSectionMetaData.questionnaire.userProject != null) {//todoreturn;
}
if (mSectionMetaData.section != null && !mSectionMetaData.section.sectionArticles.isEmpty()) {//todo return;
}
使用apply后
mSectionMetaData?.apply{
//mSectionMetaData不为空的时候操作mSectionMetaData
}?.questionnaire?.apply{
//mSectionMetaData.questionnaire不为空的时候操作questionnaire
}?.section?.apply{
//section不为空的时候操作section
}?.sectionArticle?.apply{
//sectionArticle不为空的时候操作sectionArticle
}
3、分析
从结构上来看apply函数和run函数很像,唯一不同点就是它们各自返回的值不一样,run函数是以闭包形式返回最后一行代码的值,而apply函数的返回的是传入对象的本身。
4、场景
基于apply返回传入对象的本身,它适用场景稍微与run函数有点不一样。apply一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值。或者动态inflate出一个XML的View的时候需要给View绑定数据也会用到,这种情景非常常见。
使用apply前
mSheetDialogView = View.inflate(activity,R.layout.biz_exam_plan_layout_sheet_inner, null)
mSheetDialogView.course_comment_tv_label.paint.isFakeBoldText = true
mSheetDialogView.course_comment_tv_score.paint.isFakeBoldText = true
mSheetDialogView.course_comment_tv_cancel.paint.isFakeBoldText = true
mSheetDialogView.course_comment_tv_confirm.paint.isFakeBoldText = true
mSheetDialogView.course_comment_seek_bar.max = 10
mSheetDialogView.course_comment_seek_bar.progress = 0
使用之后
mSheetDialogView = View.inflate(activity, R.layout.biz_exam_plan_layout_sheet_inner, null)
.apply{course_comment_tv_label.paint.isFakeBoldText = truecourse_comment_tv_score.paint.isFakeBoldText = truecourse_comment_tv_cancel.paint.isFakeBoldText = truecourse_comment_tv_confirm.paint.isFakeBoldText = truecourse_comment_seek_bar.max = 10course_comment_seek_bar.progress = 0
}
六、 also函数
1、 简介
also函数和let函数很像,在Lambda函数块内通过 it 指代该对象。不同点就是let函数最后的返回值是最后一行的返回值而also函数的返回值是返回当前的这个对象,这一点和apply函数很像。
2、 示例代码
object.also{
//todo
}
//源码
@SinceKotlin(“1.1”)
public inline fun T.also(block: (T) -> Unit): T { block(this); return this }
使用also前
public static final void main(@NotNull String[] args) {Intrinsics.checkParameterIsNotNull(args, "args");String var2 = "testLet";int var4 = var2.length();System.out.println(var4);System.out.println(var2);}
使用also后
fun main(args: Array<String>) {val result = "testLet".also {println(it.length)1000}println(result)
}
3、分析
also函数的结构实际上和let很像唯一的区别就是返回值的不一样,let是以闭包的形式返回函数体内最后一行的值,如果最后一行为空就返回一个Unit类型的默认值。而also函数返回的则是传入对象的本身
4、场景
适用于let函数的任何场景。also函数和let很像,只是唯一的不同点就是let函数最后的返回值是最后一行的返回值而also函数的返回值是返回当前的这个对象。一般可用于多个扩展函数链式调用
七、总结
函数名 | 对象引用 | 返回值 | 是否可扩展函数 | 场景 |
---|---|---|---|---|
let | it指代当前对象 | 闭包形式返回 | 是 | 适用于处理不为null的操作场景 |
with | tthis指代当前对象或者省略 | 闭包形式返回 | 否 | 适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可 |
run | this指代当前对象或者省略 | 闭包形式返回 | 是 | 适用于let,with函数任何场景。 |
apply | this指代当前对象或者省略 | 上下文对象this | 是 | 对象配置 |
also | it指代当前对象 | 上下文对象this | 是 | 适用于let函数的任何场景,一般可用于多个扩展函数链式调用 |
Android Kotlin之let、with、run、apply、also函数的使用相关推荐
- Kotlin中let、run、with、apply及also的差别
/ 今日科技快讯 / 近日,微软刚刚发布了新版操作系统Windows 11,包括全新的设计和诸多新功能,并且能够直接运行安卓应用.该公司首席执行官兼董事长萨蒂亚·纳德拉随后接受媒体专访,他称希 ...
- Android kotlin run函数学习
继续来看一下kotlin中run函数的应用,首先看一下源码: /*** Calls the specified function [block] and returns its result.** F ...
- android studio 2.3 instant run,android studio 2.3 instant run not working
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试): 问题: I have updated android studio from 2.2 to 2.3,t ...
- Android Kotlin okhttp Retrofit 线程协程那些事
这篇文章不是用来讲概念的, 只是用来谈论一些关于Android 进程\协程那些问题 1. android 子线程中的异常会引发crash闪退吗? 答案是会的 Thread{throw RuntimeE ...
- Android: Kotlin 材料设计入门
原文:Android: Kotlin 材料设计入门 作者:Joe Howard 译者:kmyhy 更新说明:本教程由 Joe Howard 升级为 Kotlin.原教程作者是 Megha Bambra ...
- WOL wake on lan 功能 nodejs android kotlin实现
有些机器支持WOL功能,可以远程唤醒机器, 几乎所有品牌的硬件都支持WOL,由于安全原因,可能在软件上默认WOL处于关闭状态 原理 WOL(Wake on Lan),即局域网唤醒,从根本上来说是硬件设 ...
- Android Kotlin Exception处理
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/118386817 本文出自[赵彦军的博客] 往期精彩文章 Android Corou ...
- Android Kotlin协程和Retrofit结合使用
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/118085035 本文出自[赵彦军的博客] 往期精彩文章: Kotlin实战指南二十 ...
- 分析Android studio3.0的instant run开启关闭对APK大小的影响
分析Android studio3.0的instant run开启关闭对APK大小的影响 首先看下默认开启instant run的截图: Android studio2.0后新增加的功能默认开启ins ...
- Android Kotlin之Flow数据流
文章目录 Flow介绍 使用举例 常用操作符 创建操作符 回调操作符 变换操作符 过滤操作符 组合操作符 功能性操作符 末端操作符 冷流 vs 热流 SharedFlow shareIn将普通flow ...
最新文章
- 在PyTorch中进行双线性采样:原理和代码详解
- Swift 5.0 值得关注的特性:增加 ResultT, E: Error 枚举类型
- Linux find
- css的基本操作学习--css样式,选择器,hover,文字属性,文本属性,背景
- python中select用法_Python select及selectors模块概念用法详解
- Oracle统计信息中的Pending Statistics
- 海思 截图显示_三星Note10+5G国行跑分达到45万,华为海思麒麟990压力大不大?
- 自然语言处理(NLP)语义分析--文本分类、情感分析、意图识别
- 科技文献检索与计算机应用试卷,科技文献检索期末上机考试试题
- web前端需要学MySQL吗_HTML是web前端工程师必须要学的
- 搭建ORB_SLAM3在Linux下的编译和运行环境
- java.nio.channels.NotYetConnectedException: null
- 设定软件使用期限,根据网络时间保护试用软件产品的方法
- debian系linux更新时,提示“由于没有公钥,无法验证下列签名”
- 短信验证码实现(京东万象第三方接口)
- mysql命令行进行数据导入和导出
- Converting Phase Noise to Time Jitter
- 数据结构实验报告线性表的应用
- Android studio修改svn地址的问题
- 移动app商城UI模板(仿淘宝)
热门文章
- win10系统网络图标变成小地球的解决方法
- 主DNS、辅助DNS、缓存DNS和基于CDN的利用DNS服务器实现负载均衡
- 使用Ultra Librarian将bxl文件转为OrCAD Capture CIS可识别的库文件(OLB)
- ORACLE EBS常用标准表结构
- 关于Debian10的网络配置
- 重磅 | 分子生物学与遗传学经典名著——《Lewin基因XII》(中译本)
- fputc函数重写实现printf重定向
- 离职通知邮件主题写什么好_“辞职”发邮件标题怎么写?
- 互联收集金融,其实是门苦商业
- 阿里云SDK和SpringBoot maven项目中jar包冲突的解决办法