Kotlin中标准库函数(apply、let、run、with、also、takeIf、takeUnless)的使用详解

news/2024/11/27 19:30:13/

博主前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住也分享一下给大家
👉点击跳转到教程

一、apply函数

apply
apply函数可以看作是一个配置函数,你可以传入一个接收者,然后调用一系列函数来配置它以便使用,如果提供lambda表达式给 apply函数执行,它会返回配置好的接收者。
可以看到,调用一个个函数类配置接收者时,变量名就省略掉了。
这是因为,在lambda表达式里,apply能让每个配置函数都作用于接收者,
这种行为有时又叫相关作用域,因为lambda表达式里的所有函数调用都是针对接收者的,或者说,它们是针对接收者的隐时调用。

fun main() {val file1 = File("D:\\android.txt")file1.setReadable(true)//可读file1.setWritable(true)//可写file1.setExecutable(false)//不能执行/*** apply* apply函数可以看作是一个配置函数,你可以传入一个接收者,* 然后调用一系列函数来配置它以便使用,如果提供lambda表达式给* apply函数执行,它会返回配置好的接收者。** 可以看到,调用一个个函数类配置接收者时,变量名就省略掉了。* 这是因为,在lambda表达式里,apply能让每个配置函数都作用于接收者,* 这种行为有时又叫相关作用域,因为lambda表达式里的所有函数调用都是针对接收者的,* 或者说,它们是针对接收者的隐时调用。*/val file2 = File("D:\\android.txt").apply {setReadable(true)setWritable(true)setExecutable(false)}
}

二、let函数

fun main() {/*** let* let函数能使某个变量作用于其lambda表达式里,让it关键字能引用它,let与apply* 比较,let会把接收者传给lambda,而apply什么都不传,匿名函数执行完,apply会返回当前接收者* 而let会返回lambda的最后一行。*/val result = listOf(3, 2, 1).first().let {it * it}println(result)val firstElement = listOf(3, 2, 1).first()val result1 = firstElement * firstElementprintln(result1)println(formatGreeting(null))println(formatGreeting("android"))
}/*** 使用let函数与安全调用操作符,空合并操作符一起使用*/
fun formatGreeting(guestName: String?): String {return guestName?.let {"Welcome,$it."} ?: "What's your name?"
}fun formatGreeting1(guestName: String?): String {return if (guestName != null) {"Welcome $guestName"} else {"What's your name?"}
}

输出结果:

9
9
What's your name?
Welcome,android.

三、run函数

fun main() {/*** run函数* 光看作用域行为,run和apply差不多,但与apply不同,run函数不返回接收者,run返回的是lambda表达式* 也就是true或者false,都是返回匿名函数的最后一行,不只是true或false** run也能用来执行函数引用*/var file = File("D:\\android.txt")val result = file.run {readText().contains("great")}println(result)val result1 = "The people's Republic of China.".run(::isLong)println(result1)"The people's Republic of China.".run(::isLong).run(::showMessage).run(::println)
}fun isLong(name: String) = name.length >= 10
fun showMessage(isLong: Boolean): String {return if (isLong) {"Name is too long."} else {"Please rename"}
}

输出结果:

true
true
Name is too long.

四、with函数

fun main() {val result1 = "The people's Republic of China.".run {length >= 10}println(result1)/*** with函数是run的变体,它们的功能行为是一样的,但with的调用方式不一样,调用with* 时需要值参作为其第一个参数传入*/val result2 = with("The people's Republic of China.") {length >= 10}println(result2)
}

输出结果:

true
true

五、also函数的使用

also函数和let函数功能相似,和let一样,also也是把接收者作为值参传给lambda
但有一点不同:also返回接收者对象,而let返回lambda结果。
因为有这个差异,also尤其适合针对同一原始对象,利用副作用做事,既然also返回的是接收者对象
你就可以基于原始接收者对象执行额外的链式调用。

fun main() {/*** also* also函数和let函数功能相似,和let一样,also也是把接收者作为值参传给lambda* 但有一点不同:also返回接收者对象,而let返回lambda结果。* 因为有这个差异,also尤其适合针对同一原始对象,利用副作用做事,既然also返回的是接收者对象* 你就可以基于原始接收者对象执行额外的链式调用。*/var fileContents: List<String>val file = File("D://android.txt").also {println(it.name)}.also {fileContents = it.readLines()}println(fileContents)
}

输出结果如下:

android.txt
[great ssss]

六、takeIf函数

fun main() {/*** takeIf* 和其他标准函数有点不一样,takeIf函数需要判断lambda中提供的条件表达式,给出true或false结果* 如果判断结果为true,从takeIf函数返回接收者对象,如果是false,则返回null。* 如果需要判断某个条件是否满足,再决定是否可以赋值变量或执行某项任务,takeIf就非常有用,* 概念上讲,takeIf函数类似于if语句,但它的优势是可以直接在对象实例上调用,避免了临时变量* 赋值的麻烦。*/val result = File("D:\\android.txt").takeIf {it.exists() && it.canRead()}?.readText()println(result)//不同takeIf函数val file = File("D:\\android.txt")val result2 = if (file.exists() && file.canRead()) {file.readText()} else {null}println(result2)
}

输出结果:

great ssss
great ssss

七、takeUnless函数

fun main() {/*** takeIf的辅助函数takeUnless,只有判断你给定的条件结果是false时,takeUnless才会* 返回原始接收者对象*/val result = File("D:\\android.txt").takeUnless {it.isHidden}?.readText()println(result)
}

输出结果:

great ssss

http://www.ppmy.cn/news/19031.html

相关文章

C++进阶 哈希表封装unordered_map和unordered_set

作者&#xff1a;小萌新 专栏&#xff1a;C进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;使用哈希表封装unordered_map和unordered_set 哈希表源代码 我们下面会对一个 K V 模型的哈希表进行封装 使用之来模拟实现STL库中的…

Vue TypeScript 使用eval函数的坑

正常情况下&#xff0c;项目里不会用eval函数&#xff0c;但是万一要调用一个全局的js库&#xff0c;就需要用eval做些骚操作&#xff0c;这个时候编译会提示&#xff1a; is strongly discouraged as it poses security risks and may cause issues with minification. 警告是…

ARP渗透与攻防(三)之流量分析

ARP攻击-流量分析 ARP渗透与攻防(一)之ARP原理 ARP渗透与攻防(二)之断网攻击 系列文章 1.环境准备 1.kali作为攻击机 2.win10作为靶机 IP地址&#xff1a;192.168.110.11 3.网关 IP地址&#xff1a;192.168.110.1 2.kali数据包转发 出于安全考虑&#xff0c;Linux系统默…

Godot根据遮罩图移动粒子

前言 目前UI粒子特效unity引擎比较多&#xff0c;也好找资料&#xff0c;但是一般都是利用模型&#xff0c;使用3D粒子伪装2D效果。 Godot中也可以做到这一点&#xff0c;并且Godot有专门的2D粒子系统&#xff0c;可以通过一张遮罩图对粒子的位置进行设置。 godot粒子教程 …

深度学习网络---YOLO系列

深度学习网络—YOLO yolov1&#xff08;仅适用一个卷积神经网络端到端地实现检测物体的目的&#xff09; 首先将输入图片resize到448448&#xff0c;然后送入CNN网络&#xff0c;最后处理预测的结果得到检测的目标&#xff1b;yolov1的具体思想是将全图划分为SS的格子&#xf…

第五十三章 使用 ^SystemPerformance 监视性能 - InterSystems IRIS Linux 平台性能数据报告

文章目录第五十三章 使用 ^SystemPerformance 监视性能 - InterSystems IRIS Linux 平台性能数据报告第五十三章 使用 ^SystemPerformance 监视性能 - InterSystems IRIS Linux 平台性能数据报告 %SS - 使用 ALL^%SS 命令在运行过程中采集了四个样本。 Configuration * - 来自…

CSDN原创图片链接失效分析

过年花了5个小时&#xff0c;把我的所有BLOG&#xff08;200多篇&#xff09;检查了一遍&#xff0c;更正了几十处图片链接失效。 1. 现象 几个月来&#xff0c;由于在写书&#xff0c;不停地回翻自己以前的文章。结果&#xff0c;不断发现大量辛辛苦苦绘制的图片打不开了&am…

C语言之程序设计概述

1.1.1 程序的概念 程序&#xff1a;算法 数据结构 程序设计方法 语言工具和环境数据结构&#xff1a;数据的类型和数据的组织方式算法&#xff1a;对数据操作的方法和步骤 1.1.2 程序设计语言的种类 第一代语言&#xff08;机器语言&#xff09;&#xff1a;执行效率高、…