0%

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

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


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

let

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

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

简单示例:

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

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

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

来个复杂一定的例子

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

编译过后的class文件

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

apply

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

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

代码示例

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

编译过后的class文件

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

with

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

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

代码示例:

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

class文件

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

run

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

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

代码示例

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

class文件

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

总结

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

函数名 定义 参数 返回值 extension 其他
let fun <T, R> T.let(f: (T) -> R): R = f(this) it 闭包返回
apply fun T.apply(f: T.() -> Unit): T { f(); return this } 无,可以使用this this
with fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f() 无,可以使用this 闭包返回 调用方式与其他不同
run fun <T, R> T.run(f: T.() -> R): R = f() 无,可以使用this 闭包返回
坚持原创技术分享,您的支持将鼓励我继续创作!