zoukankan      html  css  js  c++  java
  • Kotlin之let,apply,with,run函数区别(转)

    转自:https://blog.csdn.net/guijiaoba/article/details/54615036

    Kotlin之let,apply,with,run函数区别


    重新整理

    重新整理了各种函数的区别,请移步到这里


    以下作废


    很长一段时间内都一直使用Kotlin这门语言,也只是纯粹使用简单语法,最近有时候写的代码,编辑器自动提示使用let等函数,然后就专门花点时间研究了下。

    let

    首先let()的定义是这样的,默认当前这个对象作为闭包的it参数,返回值是函数里面最后一行,或者指定return

    fun <T, R> T.let(f: (T) -> R): R = f(this)
    • 1

    简单示例:

    fun testLet(): Int {
        // fun <T, R> T.let(f: (T) -> R): R { f(this)}
        "testLet".let {
            println(it)
            println(it)
            println(it)
            return 1
        }
    }
    //运行结果
    //testLet
    //testLet
    //testLet
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    可以看看最后生成的class文件,代码已经经过格式化了,编译器只是在我们原先的变量后面添加了let里面的内容。

    public static final int testLet() {
        String str1 = "testLet";
        String it = (String)str1;
        int $i$a$1$let;
        System.out.println(it);
        System.out.println(it);
        System.out.println(it);
        return 1;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    来个复杂一定的例子

    fun testLet(): Int {
        // fun <T, R> T.let(f: (T) -> R): R { f(this)}
        "testLet".let {
            if (Random().nextBoolean()) {
                println(it)
                return 1
            } else {
                println(it)
                return 2
            }
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    编译过后的class文件

    public static final int testLet() {
        String str1 = "testLet";
        String it = (String)str1;
        int $i$a$1$let;
        if (new Random().nextBoolean())
        {
            System.out.println(it);
            return 1;
        }
        System.out.println(it);
        return 2;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    apply

    apply函数是这样的,调用某对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象

    fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
    • 1

    代码示例

    fun testApply() {
        // fun <T> T.apply(f: T.() -> Unit): T { f(); return this }
        ArrayList<String>().apply {
            add("testApply")
            add("testApply")
            add("testApply")
            println("this = " + this)
        }.let { println(it) }
    }
    
    // 运行结果
    // this = [testApply, testApply, testApply]
    // [testApply, testApply, testApply]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    编译过后的class文件

      public static final void testApply()
      {
        ArrayList localArrayList1 = new ArrayList();
        ArrayList localArrayList2 = (ArrayList)localArrayList1;
        int $i$a$1$apply;
        ArrayList $receiver;
        $receiver.add("testApply");
        $receiver.add("testApply");
        $receiver.add("testApply");
        String str = "this = " + $receiver;
        System.out.println(str);
        localArrayList1 = localArrayList1;
        ArrayList it = (ArrayList)localArrayList1;
        int $i$a$2$let;
        System.out.println(it);
      }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    with

    with函数是一个单独的函数,并不是Kotlin中的extension,所以调用方式有点不一样,返回是最后一行,然后可以直接调用对象的方法,感觉像是let和apply的结合。

    fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
    • 1

    代码示例:

    fun testWith() {
        // fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
        with(ArrayList<String>()) {
            add("testWith")
            add("testWith")
            add("testWith")
            println("this = " + this)
        }.let { println(it) }
    }
    // 运行结果
    // this = [testWith, testWith, testWith]
    // kotlin.Unit
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    class文件

     public static final void testWith()
      {
        Object localObject = new ArrayList();
        ArrayList localArrayList1 = (ArrayList)localObject;
        int $i$a$1$with;
        ArrayList $receiver;
        $receiver.add("testWith");
        $receiver.add("testWith");
        $receiver.add("testWith");
        String str = "this = " + $receiver;
        System.out.println(str);
        localObject = Unit.INSTANCE;
        Unit it = (Unit)localObject;
        int $i$a$2$let;
        System.out.println(it);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    run

    run函数和apply函数很像,只不过run函数是使用最后一行的返回,apply返回当前自己的对象。

    fun <T, R> T.run(f: T.() -> R): R = f()
    • 1

    代码示例

    fun testRun() {
        // fun <T, R> T.run(f: T.() -> R): R = f()
        "testRun".run {
            println("this = " + this)
        }.let { println(it) }
    }
    // 运行结果
    // this = testRun
    // kotlin.Unit
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    class文件

      public static final void testRun()
      {
        Object localObject = "testRun";
        String str1 = (String)localObject;
        int $i$a$1$run;
        String $receiver;
        String str2 = "this = " + $receiver;
        System.out.println(str2);
        localObject = Unit.INSTANCE;
        Unit it = (Unit)localObject;
        int $i$a$2$let;
        System.out.println(it);
      }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    总结

    怎么样,是不是看晕了,没关系,我们来总结下。

    函数名定义参数返回值extension其他
    let fun T.let(f: (T) -> R): R = f(this) it 闭包返回  
    apply fun T.apply(f: T.() -> Unit): T { f(); return this } 无,可以使用this this  
    with fun with(receiver: T, f: T.() -> R): R = receiver.f() 无,可以使用this 闭包返回 调用方式与其他不同
    run fun T.run(f: T.() -> R): R = f() 无,可以使用this 闭包返回
  • 相关阅读:
    Android性能调优实例
    Android移动端网络优化
    性能优化之Java(Android)代码优化
    Android性能优化之布局优化
    Android性能优化之数据库优化
    Android性能优化系列总篇
    ViewGroup的事件分发机制
    Apk大瘦身
    不安装APK直接启动应用
    Intent详解
  • 原文地址:https://www.cnblogs.com/weizhxa/p/9253627.html
Copyright © 2011-2022 走看看