Mastering Kotlin standard functi

作者: IMSk | 来源:发表于2018-08-02 11:16 被阅读13次

    kotlin 在 standard.kt 文件中 提供好几个挺有趣的方法。用的好的话,会让我们代码可读性更强,更加简洁。

    昨晚看到一篇文章讲这几个方法,讲的非常到位。 《Mastering Kotlin standard functions: run, with, let, also and apply》

    至于什么时候选择用哪一个方法的时候,可以上一张总结的图:

    image

    T.run

    先来看看定义:

    image

    run 其实有两个定义:

    * 接受一个 block,返回block执行结果,这个block里面捕获到的'this'是block之外的作用域.
    * T.run 同样也是接受一个block,只是这个block是属于T的一个`扩展` ,返回block执行结果,这个block里面捕获到的'this'是`T`.
    

    如何使用:

    fun test() {
      var mood = "I am sad"
    
      run {
          // 这里捕获到的this是外层的作用域
          val mood = "I am happy"
          println(mood) // I am happy
      }
      println(mood)  // I am sad
    }
    

    这种写法,我们可以在任意位置,新起一个代码块,而且可以访问到上下文的,最终运算出来一个结果值,可以让代码看起来更简洁, 比如:

     run {
           if (firstTimeView) introView else normalView
         }.show()
    

    为了区分一下两个run,再举个例子:

    image

    T.with

    先来看看定义:

    image
      接受一个T,和一个T的扩展block,返回block执行的结果值
    

    如何使用:

    //with(webview.settings,{...}) 接受了一个setting对象和一个block.
    // kotlin可以简写把block直接跟着方法末端(尾闭包的概念)
    with(webview.settings) {
       //这里可以对T也就是settings进行初始化操作
      javaScriptEnabled = true
      databaseEnabled = true
    }
    

    T.let

    先来看看定义:

    image
      接受一个T为参数的block,返回block执行的结果值
    

    如何使用:

     stringVariable?.run {
        println("The length of this String is $length")
    }
    
    // Similarly.
    stringVariable?.let {
        println("The length of this String is ${it.length}")
    }
    

    可以看到 let 和 run 非常相似,他们都可以做到接受前面的T,作为block的参数,但是let在这一块的做法更为直接明确一些,因为T在block有自己的别名了的,叫做'it',而这里的this就类似普通的 run 方法,可以访问到上下文。所以,let有一个小小的用法,类似这样:

    stringVariable?.let {
        nonNullString ->
        println("The non null string is $nonNullString")
    }
    

    什么意思呢?

    大家都知道,kotlin中的?的用法,也就是当遇到前面一个为null的时候,后面将不会执行。所以上面的let用法就是在解包,当一个对象存在的情况的时候,做一系列相关操作。

    T.also

    先来看看定义:

    image
      接受一个T为参数的block,执行完block后,返回self。可以看到 also 和前面提到的run let with都不同,
      他的block是没有返回值的:block: (T) -> Unit。
    

    如何使用:

    // Normal approach
    fun makeDir(path: String): File  {
       val result = File(path)
       result.mkdirs()
       return result
    }
    // Improved approach
    fun makeDir(path: String) = path.let{ File(it) }.also{ it.mkdirs() }
    

    also 的block 拿到的参数是前面let吐出来的File对象,所以also可以直接去创建文件,是不是比我们在没改造之前更加简洁呢?

    T.apply

    先来看看定义:

    image
      接受一个T的扩展block,执行完block后,返回self。和 前面的also非常相似,但是不同的是apply接受的block是自己的扩展。由于是扩展block,即要拿到自己需要用this或者省略。而also闭包里面前面的T是当参数传入给了闭包,所以此时有了参数别名`it`。
    

    如何使用:

    // Normal approach
    fun createInstance(args: Bundle) : MyFragment {
       val fragment = MyFragment()
       fragment.arguments = args
       return fragment
    }
    // Improved approach
    fun createInstance(args: Bundle) 
                 = MyFragment().apply { arguments = args }
    

    正如我刚才解释中提到的,他和 also 非常相似。

    image

    相关文章

      网友评论

        本文标题:Mastering Kotlin standard functi

        本文链接:https://www.haomeiwen.com/subject/iaejvftx.html