前言
kotlin 开发中常用的几个函数,let,with,run,apply,also ,具体使用场景迷糊,开发中不知道如何使用。这里罗列出来泛型表达式,反编译之后字节码进行对比,方便记忆
| 函数名 | 定义inline的结构 | 函数体内使用的对象 | 返回值 | 是否是扩展函数 | 适用的场景 |
|---|---|---|---|---|---|
| let | fun | it指代当前对象 | 闭包 | 是 | 适用于处理不为null的操作场景 |
| with | fun | this指代当前对象或者省略 | 闭包 | 否 | 类对象连续调用类属性和方法的位置 |
| run | fun | this指代当前对象或者省略 | 闭包 | 是 | 适用于let,with函数任何场景。 |
| apply | fun T.apply(block: T.() -> Unit): T { block(); return this } | this指代当前对象或者省略 | this | 是 | builder模式使用地方 |
| also | fun T.also(block: (T) -> Unit): T { block(this); return this } | it指代当前对象 | this | 是 | builder模式使用地方 |
注意kotlin lambda语法:
block: (T) -> R lambda 表达式声明。
block: T.() -> R 带接收者的lambda表达式声明,这种写法可以在 block 中使用 this 关键字代表 T实参 使用
fun main() {
val str=123
//① val combinStr=str.let { "$str world" }
//② val combinStr= with(str) {
// "$str world"
// }
//③ val combinStr=str.run { "$str world " }
//④ val combinStr=str.apply { "$str world" }
//⑤ val combinStr=str.also { "$str world" }
println(combinStr)
}
//泛型 T/R, [入参T返回 R]
//① funletT.let(block: (T) -> R): R = block(this) //② fun with(receiver: T, block: T.() -> R): R = receiver.block() //③ fun T.run(block: T.() -> R): R = block() //④ fun T.apply(block: T.() -> Unit): T { block(); return this } //⑤ fun T.also(block: (T) -> Unit): T { block(this); return this }
//① funT.let(block: (T) -> R): R = block(this) fun main() { val str=123 val combinStr=str.let { "$str world" } println(combinStr) } package letrunwithalsoapply; import kotlin.metadata; import kotlin.jvm.functions.Function1; import kotlin.jvm.internal.Intrinsics; import org.jetbrains.annotations.NotNull; @metadata( mv = {1, 6, 0}, k = 2, xi = 2, d1 = {"u0000u0012nu0000nu0002u0010u0002nu0002bu0004nu0002u0018u0002nu0002bu0002u001au0006u0010u0000u001au00020u0001u001a/u0010u0002u001au0002Hu0003"u0004bu0000u0010u0004"u0004bu0001u0010u0003*u0002Hu00042u0012u0010u0005u001au000eu0012u0004u0012u0002Hu0004u0012u0004u0012u0002Hu00030u0006¢u0006u0002u0010u0007¨u0006b"}, d2 = {"main", "", "let", "R", "T", "block", "Lkotlin/Function1;", "(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;", "untitled2"} ) public final class LetRunAlsoWithApplyKt { public static final void main() { final int str = 123; String combinStr = (String)let(Integer.valueOf(str), (Function1)(new Function1() { // $FF: synthetic method // $FF: bridge method public Object invoke(Object var1) { return this.invoke(((Number)var1).intValue()); } @NotNull public final String invoke(int it) { return str + " world"; } })); System.out.println(combinStr); } // $FF: synthetic method public static void main(String[] var0) { main(); } public static final Object let(Object $this$let, @NotNull Function1 block) { Intrinsics.checkNotNullParameter(block, "block"); return block.invoke($this$let); }
}
with//② funrunwith(receiver: T, block: T.() -> R): R = receiver.block() fun main() { val str=123 val combinStr= with(str) { "$str world" } println(combinStr) } package letrunwithalsoapply; import kotlin.metadata; import kotlin.jvm.functions.Function1; import kotlin.jvm.internal.Intrinsics; import org.jetbrains.annotations.NotNull; @metadata( mv = {1, 6, 0}, k = 2, xi = 2, d1 = {"u0000u0016nu0000nu0002u0010u0002nu0002bu0005nu0002u0018u0002nu0002u0018u0002nu0002bu0002u001au0006u0010u0000u001au00020u0001u001a8u0010u0002u001au0002Hu0003"u0004bu0000u0010u0004"u0004bu0001u0010u00032u0006u0010u0005u001au0002Hu00042u0017u0010u0006u001au0013u0012u0004u0012u0002Hu0004u0012u0004u0012u0002Hu00030u0007¢u0006u0002bb¢u0006u0002u0010t¨u0006n"}, d2 = {"main", "", "with", "R", "T", "receiver", "block", "Lkotlin/Function1;", "Lkotlin/ExtensionFunctionType;", "(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;", "untitled2"} ) public final class LetRunAlsoWithApplyKt { public static final void main() { final int str = 123; String combinStr = (String)with(Integer.valueOf(str), (Function1)(new Function1() { // $FF: synthetic method // $FF: bridge method public Object invoke(Object var1) { return this.invoke(((Number)var1).intValue()); } @NotNull public final String invoke(int $this$with) { return str + " world"; } })); System.out.println(combinStr); } // $FF: synthetic method public static void main(String[] var0) { main(); } public static final Object with(Object receiver, @NotNull Function1 block) { Intrinsics.checkNotNullParameter(block, "block"); return block.invoke(receiver); } }
```kotlin //③ funapplyT.run(block: T.() -> R): R = block() fun main() { val str=123 val combinStr=str.run { "$str world " } println(combinStr) } package letrunwithalsoapply; import kotlin.metadata; import kotlin.jvm.functions.Function1; import kotlin.jvm.internal.Intrinsics; import org.jetbrains.annotations.NotNull; @metadata( mv = {1, 6, 0}, k = 2, xi = 2, d1 = {"u0000u0016nu0000nu0002u0010u0002nu0002bu0004nu0002u0018u0002nu0002u0018u0002nu0002bu0002u001au0006u0010u0000u001au00020u0001u001a4u0010u0002u001au0002Hu0003"u0004bu0000u0010u0004"u0004bu0001u0010u0003*u0002Hu00042u0017u0010u0005u001au0013u0012u0004u0012u0002Hu0004u0012u0004u0012u0002Hu00030u0006¢u0006u0002bu0007¢u0006u0002u0010b¨u0006t"}, d2 = {"main", "", "run", "R", "T", "block", "Lkotlin/Function1;", "Lkotlin/ExtensionFunctionType;", "(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;", "untitled2"} ) public final class LetRunAlsoWithApplyKt { public static final void main() { final int str = 123; String combinStr = (String)run(Integer.valueOf(str), (Function1)(new Function1() { // $FF: synthetic method // $FF: bridge method public Object invoke(Object var1) { return this.invoke(((Number)var1).intValue()); } @NotNull public final String invoke(int $this$run) { return str + " world "; } })); System.out.println(combinStr); } // $FF: synthetic method public static void main(String[] var0) { main(); } public static final Object run(Object $this$run, @NotNull Function1 block) { Intrinsics.checkNotNullParameter(block, "block"); return block.invoke($this$run); } }
//④ fun T.apply(block: T.() -> Unit): T { block(); return this }
fun main() {
val str=123
val combinStr=str.apply { "$str world" }
println(combinStr)
}
import kotlin.metadata;
@metadata(
mv = {1, 6, 0},
k = 2,
xi = 2,
d1 = {"u0000bnu0000nu0002u0010u0002nu0000u001au0006u0010u0000u001au00020u0001¨u0006u0002"},
d2 = {"main", "", "untitled2"}
)
public final class LetRunAlsoWithApplyKt {
public static final void main() {
int str = 123;
int var4 = false;
(new StringBuilder()).append(str).append(" world").toString();
System.out.println(str);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
also
//⑤fun T.also(block: (T) -> Unit): T { block(this); return this }
fun main() {
val str=123
val combinStr=str.also { "$str world" }
println(combinStr)
}
package letrunwithalsoapply;
import kotlin.metadata;
@metadata(
mv = {1, 6, 0},
k = 2,
xi = 2,
d1 = {"u0000bnu0000nu0002u0010u0002nu0000u001au0006u0010u0000u001au00020u0001¨u0006u0002"},
d2 = {"main", "", "untitled2"}
)
public final class LetRunAlsoWithApplyKt {
public static final void main() {
int str = 123;
int var4 = false;
(new StringBuilder()).append(str).append(" world").toString();
System.out.println(str);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
Kotlin系列之let、with、run、apply、also函数的使用
this还是it?合理使用with操作符



