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

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

一、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 * firstElement
    println(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


目录
相关文章
|
6天前
|
Kotlin
Kotlin - 标准函数(with、run和apply)
Kotlin - 标准函数(with、run和apply)
6 1
|
7月前
|
存储 Java 编译器
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(下)
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(下)
35 0
|
7月前
|
Java Android开发 开发者
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(上)
Kotlin 学习笔记(四)—— 作用域函数、inline 关键字、反引号等 Kotlin 基本用法(上)
53 0
|
9月前
|
安全 Java 编译器
Kotlin 学习笔记(一)—— 基本类型、函数、lambda、类与对象的写法
Kotlin 作为 Android 开发的首选语言,其基础语法和特性需要重点学习。本文概括总结了 Kotlin 的基本类型、关键字、函数、闭包、高阶函数、类与对象等核心知识点,并给出示例代码进行讲解。
154 0
Kotlin 学习笔记(一)—— 基本类型、函数、lambda、类与对象的写法
|
23小时前
|
移动开发 安全 Android开发
构建高效Android应用:采用Kotlin协程优化网络请求
【5月更文挑战第21天】 在移动开发领域,尤其是针对Android平台,网络请求的处理一直是影响应用性能和用户体验的关键因素。随着现代应用对实时性和响应速度要求的不断提高,传统的同步阻塞或异步回调模式已不再满足开发者的需求。本文将探讨利用Kotlin协程来简化Android应用中的网络请求处理,实现非阻塞的并发操作,并提升应用的整体性能和稳定性。我们将深入分析协程的原理,并通过一个实际案例展示如何在Android项目中集成和优化网络请求流程。
|
1天前
|
移动开发 Android开发 开发者
构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第21天】在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着Kotlin语言在Android平台的广泛采纳,其并发处理的强大工具—协程(Coroutines),已成为提升应用响应性和效率的关键因素。本文将深入分析Kotlin协程的核心原理,探讨其在Android开发中的优势,并通过实例演示如何有效利用协程来优化应用性能,打造更加流畅的用户体验。
9 4
|
1天前
|
安全 Java Android开发
构建高效Android应用:Kotlin与Jetpack的实践指南
【5月更文挑战第20天】 在移动开发的世界中,效率和性能始终是开发者追求的核心目标。随着技术的不断进步,Kotlin语言以其简洁、安全和实用的特性成为了Android开发的首选语言。与此同时,Android Jetpack组件的推出,为开发者提供了一套高质量的库、工具和指南,以简化应用程序的开发过程。本文将探讨如何结合Kotlin语言和Jetpack组件来构建一个高效的Android应用,涵盖从项目初始化到性能优化的全过程。
|
1天前
|
调度 数据库 Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第20天】 在移动开发领域,性能优化和流畅的用户体验始终是开发者追求的核心目标。随着Kotlin语言的普及,其提供的协程功能已经成为实现这一目标的重要工具。本文将深入探讨Kotlin协程在Android开发中的应用优势,并通过实例代码演示如何在应用中有效利用协程进行异步编程、网络请求和数据库操作。通过这些实践,开发者可以更好地理解并运用协程,以提升应用的性能和响应速度。
|
1天前
|
测试技术 Android开发 开发者
构建高效Android应用:Kotlin协程与Flow的完美融合
【5月更文挑战第20天】 在现代Android开发中,提升应用性能和用户体验是至关重要的任务。Kotlin作为一种现代化的编程语言,以其简洁、安全和易于理解的特点被广泛采用。特别是Kotlin协程和Flow这两个特性,它们为处理异步任务和数据流提供了强大而灵活的工具。通过深入探索Kotlin协程和Flow的结合使用,本文将揭示如何利用这些特性构建更加高效且响应迅速的Android应用。我们将探讨实现细节,以及如何通过这种技术堆栈来优化资源管理和用户界面的流畅度。
|
4天前
|
移动开发 Android开发 UED
构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第17天】 在移动开发领域,尤其是针对Android平台,性能优化和流畅的用户体验始终是开发者追求的目标。Kotlin作为一种现代的编程语言,自引入Android开发以来,其简洁、安全和互操作性的特点受到广泛欢迎。特别是Kotlin协程的推出,为解决Android平台上的并发编程问题提供了新的思路。本文将深入探讨Kotlin协程的核心优势,并通过实例展示如何在Android应用中有效利用协程来提高响应性和稳定性,从而改善整体的用户体验。