当前位置:网站首页>Kotlin常用函数 let,with,apply,also,run
Kotlin常用函数 let,with,apply,also,run
2022-06-21 16:05:00 【灯塔@kuaidao】
前言
kotlin 开发中常用的几个函数,let,with,run,apply,also ,他们都是范围函数,具体使用场景迷糊,开发中不知道如何使用。这里罗列出来泛型表达式,反编译之后字节码进行对比,方便记忆
| 函数名 | 定义inline的结构 | 函数体内使用的对象 | 返回值 | 是否是扩展函数 | 适用的场景 |
|---|---|---|---|---|---|
| let | fun <T, R> T.let(block: (T) -> R): R = block(this) | it指代当前对象 | 闭包 | 是 | 适用于处理不为null的操作场景 |
| with | fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() | this指代当前对象或者省略 | 闭包 | 否 | 类对象连续调用类属性和方法的位置 |
| run | fun <T, R> T.run(block: T.() -> R): R = block() | 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]
//① fun <T, R> T.let(block: (T) -> R): R = block(this)
//② fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
//③ fun <T, R> 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 }
let
//① fun <T, R> T.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 = {
"\u0000\u0012\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0004\n\u0002\u0018\u0002\n\u0002\b\u0002\u001a\u0006\u0010\u0000\u001a\u00020\u0001\u001a/\u0010\u0002\u001a\u0002H\u0003\"\u0004\b\u0000\u0010\u0004\"\u0004\b\u0001\u0010\u0003*\u0002H\u00042\u0012\u0010\u0005\u001a\u000e\u0012\u0004\u0012\u0002H\u0004\u0012\u0004\u0012\u0002H\u00030\u0006¢\u0006\u0002\u0010\u0007¨\u0006\b"},
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
//② fun <T, R> with(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 = {
"\u0000\u0016\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u001a\u0006\u0010\u0000\u001a\u00020\u0001\u001a8\u0010\u0002\u001a\u0002H\u0003\"\u0004\b\u0000\u0010\u0004\"\u0004\b\u0001\u0010\u00032\u0006\u0010\u0005\u001a\u0002H\u00042\u0017\u0010\u0006\u001a\u0013\u0012\u0004\u0012\u0002H\u0004\u0012\u0004\u0012\u0002H\u00030\u0007¢\u0006\u0002\b\b¢\u0006\u0002\u0010\t¨\u0006\n"},
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);
}
}
run
```kotlin
//③ fun <T, R> T.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 = {
"\u0000\u0016\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0004\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u001a\u0006\u0010\u0000\u001a\u00020\u0001\u001a4\u0010\u0002\u001a\u0002H\u0003\"\u0004\b\u0000\u0010\u0004\"\u0004\b\u0001\u0010\u0003*\u0002H\u00042\u0017\u0010\u0005\u001a\u0013\u0012\u0004\u0012\u0002H\u0004\u0012\u0004\u0012\u0002H\u00030\u0006¢\u0006\u0002\b\u0007¢\u0006\u0002\u0010\b¨\u0006\t"},
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);
}
}
apply
//④ 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 = {
"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
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 = {
"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
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();
}
}
总结
基本上 apply 和 with 所做的事情就是对提供给它的接收者调用扩展函数类型的参数。 apply 函数被声明为这个接收者的扩展函数,而 with 函数把却把它作为第一个参数。另外 , apply 返回接收者本身 ,而 with 返回调用 lambda 后的结果。如果你并不关心返回值,这两个方式是可以互换使用的
边栏推荐
猜你喜欢

新增Razor组件支持代理连接RDP,JumpServer堡垒机v2.23.0发布

Stack growth direction and memory growth direction

还在用 Xshell ?试试这款炫酷的 SSH 终端工具吧,功能很强大!

In the "roll out" era of Chinese games, how can small and medium-sized manufacturers solve the problem of going to sea?

PowerPoint tutorial, how to change page orientation and slide size in PowerPoint?

贝叶斯公式的两种理解
![[graduation n-year series] the fourth year of graduation](/img/0a/e7d903dec475c54ba1277fe133963f.png)
[graduation n-year series] the fourth year of graduation

Fisher信息量检测对抗样本代码详解

【mysql学习笔记18】约束

Mqtt of NLog custom target
随机推荐
Readjustment of move protocol beta to expand the total prize pool
程序员进修之路
建立自己的网站(11)
NLog自定义Target之MQTT
数据类型
类、接口、函数
rtmp webrtc 协议 openssl 等安装
What does container cloud mean? What is the difference with fortress machine?
JetPack compose 状态提升(二)
牛客网:大数加法
牛客网:验证IP地址
20 pygame模块制作一个跳跃的小球游戏
Kotlin DSL构建
List set map in kotlin
【Leetcode】297. Serialization and deserialization of binary tree (difficult)
Variables and pointers
第13周总结博客(校历第15周)动态规划总结
Many software companies are actually "jokes"
面向流动人口管理的人脸验证系统设计及实现 论文+答辩PPT+项目工程文件
疫情数据对应的大陆和全球的矢量数据下载,基于geojson转shp