参考链接

https://www.kotlincn.net/docs/reference/scope-functions.html

背景介绍

1.本节主要讲述几个Kotlin库提供的几个方便的方法

let、run、with、apply 以及 also

takeIf以及 takeUnless

2.let、run、with、apply 以及 also的主要作用是在对象的上下文中执行代码块

3.当对一个对象调用这样的函数并提供一个 lambda 表达式时,它会形成一个临时作用域。在此作用域中,可以访问该对象而无需其名称。这些函数称为作用域函数

该作用域可以理解为花括号之内的区域

4.let、run、with、apply 以及 also的主要区别在于他们在作用域中如何引用自身以及他们作用域的返回值

5.takeIf 及 takeUnless的主要作用是检查对象状态

apply函数详解

/*** apply函数详解** 1 apply函数返回调用者本身* 2 apply内部可以使用this代表调用者** apply可以进行链式调用*/fun main() {val info = "Cai Huijian"// 不使用apply方法println("apply 函数里面打印的this是 $info")println("info 长度是${info.length}")println("info 最后一个字符是${info[info.length - 1]}")println("info 全部转为小写:${info.lowercase(Locale.getDefault())}")println("==============")// 使用apply方法val info2 = info.apply {println("apply 函数里面打印的this是 $this")println("info 长度是${/*this.*/length}") // this 可以省略println("info 最后一个字符是${this[/*this.*/length - 1]}")println("info 全部转为小写:${/*this.*/lowercase(Locale.getDefault())}")}println(info2)// apply方法返回调用者自身 这里是infoprintln("==============")// 链式调用vs普通调用// 普通调用val file = File("D:\\a.txt")file.setExecutable(true)file.setReadable(true)println(file.readLines())// 由于apply返回调用者自身 因此可以进行链式调用println("==============")file.apply {setExecutable(true)}.apply {setReadable(true)}.apply {println(file.readLines())}// 也可以这么写file.apply {this.setExecutable(true)this.setReadable(true)println(this.readLines())}// 另外也可以这么写file.apply {file.setExecutable(true)file.setReadable(true)println(file.readLines())}
}

let函数详解

/*** let函数详解** 1 let函数返回的是lambda表达式 即根据lambda表达式最后一行不同而不同* 2 let内部可以使用it代表调用者** let的应用:与?结合用于判空* 安全调用运算符 ?. 以及 Elvis运算符(空值合并运算符)  ?:*/fun main() {// 普通方式 对集合第一个元素相加val list = listOf(6, 5, 4, 7, 8)val value1 = list.first()val res = value1 + value1println(res)// 使用let 对集合第一个元素相加val res2 = list.let {it.first() + it.first()// res2的值类型为let表达式的最后一行//true//"abc"}println(res2)println("===============")// 普通方式判空println(getMethod1(/*null*/"chj"))println(getMethod2(/*null*/"chj"))println(getMethod3(/*null*/"chj"))println(getMethod4(/*null*/"chj"))
}// 普通方式判空
fun getMethod1(value: String?): String {return if (value == null) "传入空参" else "参数不为空 $value"
}// 普通方式判空 简化版
// 这里用的是单表达式函数 当函数返回单个表达式时,可以省略花括号并且在 = 符号之后指定代码体即可
fun getMethod2(value: String?) = if (value == null) "传入空参" else "参数不为空 $value"// let方式判空 let结合? 可以方便地判空
// 安全调用运算符?. 用于可空类型变量安全调用非空类型的属性或者函数,而不会抛出空指针异常,当变量为null时,直接返回空值null,否则进行调用并返回结果
// Elvis运算符(空值合并运算符):  ?:    ?:是一个二元运算符,作用是判断可空类型时空值合并,语法为:可空类型数据 ?: 空值合并到的数据,
// Kotlin 中不存在三目运算符。当数据非空时,直接返回数据,当数据为空时,返回合并到的数据
fun getMethod3(value: String?): String {return value?.let {"参数不为空 $it"// 走到这里 value必定不为空} ?: "传入空参"
}// let方式判空 let结合? 简化版
fun getMethod4(value: String?) =value?.let {"参数不为空 $it"// 走到这里 value必定不为空} ?: "传入空参"

run 函数详解

/*** run 函数详解** 1 let函数返回的是lambda表达式 即根据lambda表达式最后一行不同而不同* 2 let内部可以使用this代表调用者** 3 使用lambda表达式链式调用*/fun main() {val str = "Huijian Cai"val res1: Float = str.run {println(this)// let内部可以使用this代表调用者true3.14f // 返回值是最后一行}println(res1)// 使用具名函数进行链式调用str.run(::isLong)//返回Boolean.run(::printText)// 根据Boolean返回不同text.run(::mapText)// 对text做处理.run(::println)// 输出textprintln("===========")// 使用匿名函数进行链式调用str.run { length > 5 }.run { if (this) "字符串合格" else "字符串太短" }.run { "[$this]" }.run { println(this) }
}fun isLong(string: String) = string.length > 5fun printText(isLong: Boolean) = if (isLong) "字符串合格" else "字符串太短"fun mapText(getShow: String) = "[$getShow]"

with 函数详解

/*** with 函数详解** 1 with函数返回的是lambda表达式 即根据lambda表达式最后一行不同而不同* 2 with内部可以使用this代表调用者** 总结 with 和 let 几乎完全一样 只不过调用方式有些许差别* with(str){* }** str.let{* }*/fun main() {val string = "abc"// 具名函数操作val r1 = with(string, ::getStrLength)val r2 = with(r1, ::getLengthInfo)val r3 = with(r2, ::getInfoMap)with(r3, ::show)// 匿名操作with(with(with(with(string) {this.length}) {"你的字符串长度为:$this"}) {"[$this]"}) {println(this)}
}fun getStrLength(string: String) = string.length
fun getLengthInfo(length: Int) = "你的字符串长度为:$length"
fun getInfoMap(info: String) = "[$info]"
fun show(content: String) = println(content)

also 函数详解

/*** also 函数详解** 1 also 函数返回的是调用者本身* 2 also 内部可以使用it代表调用者**/
fun main() {val str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"val r1 : String = str.also {// r1 始终是str本身 不会管最后一行true3434.4f454'C'1}println(r1)println("=============")str.also {println(it)// 在内部 可以使用it代表调用者本身}// 由于also始终返回调用者本身 可以进行链式调用str.also {println("原始数据1:$str")println("原始数据2:$it")}.also {println("转换为小写${it.lowercase(Locale.getDefault())}")}.also {println("end")}println(str)// 不管如何操作 原始数据不变println("==============")// 链式调用的优势// 普通调用val file = File("D:\\a.txt")file.setExecutable(true)file.setReadable(true)println(file.readLines())println()// also链式调用val fileNew:File = file.also {file.setExecutable(true)// 可以使用file或者it代表外部变量it.setReadable(true)} .also {println(file.readLines())// 也可以拆成多次also调用}println(fileNew === file)
}

takeIf 内置函数

/*** takeIf 内置函数* takeIf 简单使用** name.takeIf {true/false}* true: 返回name本身* false: 返回null*/fun main() {// 调用简单的takeIfval result = checkPermission("hjcai", "123")if (result != null) {println("欢迎 $result 登录成功")}else{println("登录失败")}println("================")// 调用 takeIf 与空合并操作符?:结合println(checkPermission2("hjcai","123"))// 真实情况下 takeIf经常和空合并操作符?: 联合使用
}private fun checkPermission(name: String, pwd: String): String? {return name.takeIf {permissionSystem(name, pwd)}
}/*** takeIf 与空合并操作符?:结合** 如果takeIf内部为true 返回name 否则返回字符串"登录失败"*/
private fun checkPermission2(name: String, pwd: String): String {return name.takeIf {permissionSystem(name, pwd)} ?: "登录失败"
}private fun permissionSystem(userName: String, userPwd: String): Boolean {return userName == "hjcai" && userPwd == "123"
}

takeUnless 内置函数

/*** takeUnless 内置函数* takeUnless与takeIf 完全相反** name.takeUnless {true/false}* true: 返回null* false: 返回name本身** name.takeIf {true/false}* true: 返回name本身* false: 返回null** 为什么需要takeUnless? takeIf一个就够了?* takeUnless的目的是 结合isNullOrBlank()判断变量是否经过初始化*/class Manager{var infoValue:String? = null
}fun main() {val manager = Manager()val r = manager.infoValue.takeUnless { it.isNullOrBlank() } ?:"没有初始化"println(r)manager.infoValue = "初始化为aaa"val r2 = manager.infoValue.takeUnless { it.isNullOrBlank() } ?:"没有初始化"println(r2)
}

Kotlin学习笔记30 补充 作用域函数相关推荐

  1. Kotlin学习笔记1——变量、函数

    Kotlin学习笔记1 (学习教材为<第一行代码(第三版)>by郭霖) 1.Kotlin概述 ​ Java虚拟机不关心class文件的编译来源,即只要是符合规格的class文件,Java虚 ...

  2. Kotlin学习笔记 第三章 函数 高阶函数 lambda表达式 内联函数

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  3. Kotlin学习笔记(二)——函数操作符内置函数

    小白笔记(持续更新中) 匿名函数 //匿名函数 fun main() {//count()方法 Returns the length of this char sequence.val len=&qu ...

  4. kotlin学习笔记——泛型及reified函数

    kotlin中的泛型与java中的差不多 class TypedClass<T>(param : T){... }val s = TypedClass<String>(&quo ...

  5. Kotlin学习笔记20 阶段复习2

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 lambda表达式 内联函数 Kotlin学习笔记 第三章 函数 高阶函数 lambda表达式 内联函数_积跬步 至千里- ...

  6. Kotlin学习笔记19 阶段复习1

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 基础部分 Kotlin学习笔记 第一章开始 第二章 基础_积跬步 至千里-CSDN博客 类与继承 Kotlin学习笔记 第 ...

  7. Kotlin学习笔记12——数据类和密封类

    Kotlin学习笔记12--数据类和密封类 前言 数据类 在类体中声明的属性 复制 componentN 解构声明 密封类 尾巴 前言 上一篇,我们学习了Kotlin中的拓展,今天继续来学习Kotli ...

  8. Kotlin 学习笔记(四)—— 协程的基础知识,面试官的最爱了~

    又是一个月没见了,坚持永远是世上最难的事情,但,往往难事才会有更大的收获.与君共勉~ 前段时间一直在学习 Compose,所以导致 Kotlin 笔记系列搁置了好久.一方面是因为 Compose 的学 ...

  9. 【Python学习笔记】第八章 函数

    [Python学习笔记]第八章 函数 文章目录 [Python学习笔记]第八章 函数 前言 8.1 定义函数 8.2 调用函数 8.2.1 使用位置参数调用函数 8.2.2 使用关键字参数调用函数 8 ...

最新文章

  1. MongoDB下载地址
  2. 不是计算机专业学python能找到工作吗-python学习难不难?非计算机专业也能学吗?...
  3. 7z制作自解压安装包
  4. 曾是微信最大对手的它,如今却黯然退场,一代即时通讯App就此谢幕!
  5. 34.MySQL的高级安装和升级
  6. 【RAC】 RAC For W2K8R2 安装--创建ASM磁盘组(六)
  7. 计算机控制系统第三次作业,城市轨道交通能控制系统第三次作业.ppt
  8. web前端程序员两年学习经验与总结
  9. 2021谷歌IO大会内容
  10. html取消select下拉,jquery取消选择select下拉框
  11. MT【258】椭圆第三定义
  12. Qt的各版本直接下载地址
  13. 四川师范大学自然地理(1-地球)90分以上版本
  14. (计算机体系结构)7.3 基于硬件的前瞻执行
  15. 微服务架构——马丁弗勒
  16. 人工智能之地形导航系统
  17. “粽子第一股“来了!老字号五芳斋还有新故事?
  18. Git的使用(保姆级教程)
  19. 为什么安装step7时要重启计算机,Step7 安装总是重启的解决办法
  20. 利用Python轻松实现抠图,背景色更换

热门文章

  1. 一个高质量的程序应具备哪些条件?_有料!报考云南省考公务员,应具备哪些条件?...
  2. 猎豹浏览器打飞机_墙内最好浏览器,微软带来完整版谷歌浏览器,扩展、同步无限制!...
  3. java静态变量重复new_Java非静态成员变量之死循环(详解)
  4. MAVLink 协议解析之XML定义篇
  5. API的String 一些用法
  6. 微信小程序|个人简历
  7. 【jquery】find() 方法,filter()方法和children()方法
  8. 学习C#十五天的总结
  9. windows 编程随笔——输出文本WM_PAINT消息|有效矩形和无效矩形
  10. python opencv用法中文教程