Kotlin标准库函数使用分析及介绍

目录
  • 1.apply 函数
  • 2.let 函数
  • 3.run函数
  • 4.with 函数
  • 5.also
  • 6.takeIf
  • 7.takeUnless

1.apply 函数

apply函数可以看做是一个配置函数。针对apply函数的调用者做一些配置,并把调用者返回。

示例:下面apply的调用者是file,调用完之后,返回的还是file,并在apply函数中,针对file做了一些配置。

    val file = File("d:\\hello.txt").apply {
        setWritable(true)
        setReadable(true)
        setExecutable(false)
    }

apply源码分析:

1)apply 用inline修饰,是一个内联函数。

2)定义了一个<T>泛型,T.apply 调用者就是T,:T apply返回的类型也是T

上面的file就相当于T

3)再看apply的参数:block: T.() -> Unit。这是一个匿名函数,T.()->说明接收的是T的函数返回的是Unit类型。

4)在apply内部 调用了这个匿名函数block()也就是T的

5)return this,就是apply 的返回值,返回的是当前调用apply函数的对象。

public inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

2.let 函数

let函数会把调用者作为参数传到lambda表达式里,可以用it来代替它使用。函数执行完毕,lambda表达式返回的结果,就是let函数返回的结果。

    val hello = "Hello world".let {
        it.replace("world","kotlin")
    }
    //打印结果 Hello kotlin
    println(hello)

看下let函数的定义:

1)let函数也是一个内联函数。

2)定义了两个泛型<T,R> T.let(),说明T是let的调用者。

3)block: (T) -> R 说明let接收的是一个匿名函数,匿名函数的参数是T,返回值是R

4): R 说明let函数的返回在也是R,也就是定义的匿名函数的返回值。

5)return block(this) 把当前调用者当做参数传进来,lambda执行结果返回

上面的示例,调用let后,会把调用者当做参数传递到匿名函数也就是lambda中,并把lambda的执行结果,当做是let的结果返回。

inline fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

3.run函数

run函数和apply差不多,可以给调用者做配置。唯一的差别是apply返回的是当前调用者对象,而run返回的是lambda执行的结果。

    val text = File("d:\\hello.txt").run {
        setWritable(true)
        setReadable(true)
        setExecutable(false)
        readText()
    }
    println(text)

run函数分析:

1)run函数也是一个内联函数。

2)有两个泛型<T,R>,T是当前调用者,R是返回值

3)run接收一个lambda :block: T.() -> R 调用T的方法,并且把执行结果返回

4): R lambda的执行结果,就是run函数的执行结果。我们知道lambda默认会把最后一行的结果返回。

5)return block() 返回lambda的执行结果

inline fun <T, R> T.run(block: T.() -> R): R {
    return block()
}

4.with 函数

with函数是run的变体,他们的功能是一样的。唯一的不同是调用方式,调用with时,第一个参数需要传入一个值参。

    val hello = "Hello World"
    val h2 = with(hello) {
        replace("World", "Kotlin")
    }
    println(h2)

源码分析:

with接收两个参数,第一个是传入的值参,第二个是一个lambda表达式。

inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}

5.also

also函数和let函数类似,also也是把调用者作为参数传递给lambda,不同点是let返回的是lambda的执行结果,而also返回的是当前调用者对象,这点和apply类似。

这对这个特点,可以实现调用者的链式调用。

举个简单列子。

虽然对hello做了substring,但并不会改变hello的初始值。因为最后返回的还是调用者对象本身。

    val hello = "Hello world".also {
        println(it.count())
    }.also{
        println(it.substring(0,5))
    }
    println(hello)

源码分析:

block: (T) -> Unit also接收一个lambda,这个lambda把调用者T当参数传进来了,block(this)。

return this 又把当前对象返回回去了。

inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

6.takeIf

takeIf需要判断lambda表达式中结果,如果true则返回调用者对象,如果是false,则返回null。

如果需要判断某个条件是否满足,再决定是否可以给变量赋值或执行某项任务时,takeIf就很好用。takeIf类似于if语句。

示例:如果flag为true,则给hello赋值“Hello world”。

如果flag为false,则返回null,但是后面又有一个?:判断,就会给hello赋值“hello null”

    var flag = false
    val hello = "Hello world".takeIf { false } ?: "hello null"
    println(hello)

源码分析:

从if (predicate(this)) this else null可以看出,如果predicate(this)为true则返回调用者this否则返回null

 inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    return if (predicate(this)) this else null
}

通过源码分析,takeIf也会把调用者T当做参数传到lambda中,这样我们在lambda中就可以针对调用者做判断,满足某些条件则返回调用者对象,如果不满足,则返回null。

    val hello = "Hello world".takeIf {
        it.count() > 15
    } ?: "hello kotlin world"
    println(hello)

7.takeUnless

takeUnless刚好和takeIf相反,只有给定条件为false时,才会返回takeUnless调用者对象,否则返回null。

    val hello = "Hello world".takeUnless {
        it.count() > 15
    } ?: "hello kotlin world"
    println(hello)

源码:

if (!predicate(this)) 刚好和takeIf中的相反。

inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
    return if (!predicate(this)) this else null
}

到此这篇关于Kotlin标准库函数使用分析及介绍的文章就介绍到这了,更多相关Kotlin标准库函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Kotlin函数使用示例教程

    目录 我们先看看简单的函数 我们写一个求和函数 函数头 函数体 调用函数非常简单 反编译Java源代码步骤 接下来我们来看看匿名函数 这是接口的声明 我们先看看简单的函数 // 前面的文章我们了解到它是入口函数 fun main() { } // 对应的Java 语言,熟悉的Java 的朋友会发现,哈哈,这就是一个Java静态方法 // 我们通过两种语言的对比,能够对函数有一个更好的理解 public static final void main() { } // 如果没有 Java 基础,不适

  • Kotlin 嵌套函数开发技巧详解

    目录 1.嵌套函数 2.@JvmOverloads快捷实现函数重载 3.延迟初始化lateinit var 4.@JvmField减少属性set和get方法的生成 1.嵌套函数 业务开发中,我们可能会遇到这样一个场景:一个函数只会被某一处多次调用,且不想让这个函数在该类的其他地方调用,这个时候就需要对这个函数的访问性进行进一步限制. private是无法满足的,这个时候我们就可以使用嵌套函数提供更好的封装: fun test1() { //被限制访问行的函数 fun test2(content:

  • Kotlin扩展函数超详细介绍

    目录 1.扩展函数 2.infix 关键字 3.扩展函数文件 4.重命名扩展函数 1.扩展函数 1)当我们没法接触某个类的定义,或者某个类没有用open修饰无法继承时,我们可以通过扩展函数,来实现该类功能的扩展.扩展函数,可以扩展自定义类.String类以及kotlin标准库中的其他类. 2)定义扩展函数和定义一般函数差不多.唯一的不同就是,定义扩展函数时,除了函数定义外,还需指定给哪个类进行扩展.如:fun String.addExtention() = "Kotlin: ".plu

  • Kotlin函数式编程超详细介绍

    目录 1.函数式编程 2.函数类别 3.变换函数(transform) 4.过滤函数(filter) 5.合并函数(combine) 1.函数式编程 我们都知道java是面向对象编程范式.在java的世界,一切皆对象. 函数式编程范式是有抽象数学的lambda演算发展而来,主要依赖高阶函数返回的数据,这些高级函数专用于处理各种集合,可以方便的联合多个函数构建链式操作,以创建复杂的计算行为. 所谓高级函数就是以函数为参数或返回值是函数的函数.这点,前面的文章,有过简单介绍. 2.函数类别 一个函数

  • Kotlin标准库函数使用分析及介绍

    目录 1.apply 函数 2.let 函数 3.run函数 4.with 函数 5.also 6.takeIf 7.takeUnless 1.apply 函数 apply函数可以看做是一个配置函数.针对apply函数的调用者做一些配置,并把调用者返回. 示例:下面apply的调用者是file,调用完之后,返回的还是file,并在apply函数中,针对file做了一些配置. val file = File("d:\\hello.txt").apply { setWritable(tru

  • Kotlin by关键字作用及使用介绍

    目录 1.Kotlin委托 2.类委托 3.属性委托 3.1定义一个被委托的类 3.2标准委托 3.3把属性存储在映射中 3.4Not Null 1.Kotlin委托 在委托模式中,两个对象参与处理同一请求,接受请求的对象讲请求委托给另外一个对象来处理.Kotlin直接支持委托模式,更加优雅,简洁.kotlin通过关键字by实现委托. 2.类委托 类的委托即一个类中定义的方法实际是调用另一个类的对象的方法来实现的. 以下实例中派生类Derived继承了接口Base所有方法,并且委托一个传入的Ba

  • Android Intent传递数据底层分析详细介绍

    Android  Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没有想过这样一个问题:ActivityB中获取到的对象跟上一个Activity中的那个对象有什么关系? 换句话说就是,我在ActivityB中通过Intent获取的对象跟ActivityA中的那个对象,有没有可能是同一个对象? 按照常理来说,博主提出一个设想后续的就是证明过程了,但是我要遗憾的告诉你,

  • Android  Intent传递数据底层分析详细介绍

    Android  Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没有想过这样一个问题:ActivityB中获取到的对象跟上一个Activity中的那个对象有什么关系? 换句话说就是,我在ActivityB中通过Intent获取的对象跟ActivityA中的那个对象,有没有可能是同一个对象? 按照常理来说,博主提出一个设想后续的就是证明过程了,但是我要遗憾的告诉你,

  • Kotlin协程的启动方式介绍

    目录 1.GlobalScope.launch 2.runBlocking 启动协程 3.async启动协程 启动协程的基本方式 1.GlobalScope.launch 代码示例: fun testGlobalScope() { GlobalScope.launch { println("Coroutinue started!") delay(1000L) println("Hello World!") } println("After launch!&

  • Kotlin挂起函数的详细介绍

    Kotlin 协程的优势: 解决回调地狱的问题. 以同步的方式完成异步任务. 示例: fun main() { runBlocking { val a = getA() println(a) val b = getB(a) println(b) val c = getC(b) println(c) } } suspend fun getA(): String { withContext(Dispatchers.IO) { delay(2000L) } return "A content"

  • Kotlin类的继承实现详细介绍

    1.在kotlin中,默认类都是封闭的closed的.如果要让某个类开放继承,必须用open关键字修饰 类中的方法默认也是关闭的.如果需要子类复写父类的方法,也必须用open修饰. 1)定义父类,用open将类继承打开.用open将函数的复写打开. //父类必须用open修饰,才能够被继承 open class Person(val name:String) { var age = 0 //父类定义的函数,必须有open修饰,子类才能复写 open fun doWork(){ println("

  • Kotlin中@JvmOverloads注解作用示例介绍

    在Kotlin中@JvmOverloads注解的作用:指示Kotlin编译器为此函数生成替换默认参数值的重载. 如果一个方法有N个参数,其中M个具有默认值,则会生成M个重载. 第一个重载采用N-1个参数(最后一个采用默认值),第二个采用N-2个参数,依此类推. 因为在 Kotlin 中可以调用具有默认参数值的方法或者构造函数,但是在 Java 代码调用相应 Kotlin 代码却不行,及Java 代码不能调用Kotlin 中定义的具有默认参数的重载函数或构造函数.@JvmOverloads 就是用

  • Kotlin作用域函数使用示例详细介绍

    目录 1 let 2 run 3 with 4 apply 5 also 这里我们将介绍Kotlin 5个作用域函数:let,run,with,apply,also. 1 let let 可用于范围界定和空值检查.在对象上调用时,let 执行给定的代码块并返回其最后一个表达式的结果.对象可通过引用它(默认情况下)或自定义名称在块内进行访问. 所以,总结起来,let 有如下三大特征: // 重点11:使用it替代object对象去访问其公有的属性 & 方法 object.let{ it.todo(

  • Android中使用tcpdump、wireshark进行抓包并分析技术介绍

    本文主要介绍如何使用tcpdump和wireshark对Android应用程序进行抓包并分析,需要说明的是在抓包之前,你的Android设备必须root过了,另外你的电脑必须有Android SDK环境. 下载并安装tcpdump tcpdump链接:http://www.tcpdump.org/ 选择一个版本下载并解压提取出其中呃tcpdump文件,然后push到你的手机上去: 复制代码 代码如下: adb push c:\tcpdump /data/local/tcpdump 进一步操作:

随机推荐