Kotlin函数 ⑦ ( 内联函数 | Lambda 表达式弊端 | “ 内联 “ 机制避免内存开销 - 将使用 Lambda 表达式作为参数的函数定义为内联函数 | 内联函数本质 - 宏替换 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin函数 ⑦ ( 内联函数 | Lambda 表达式弊端 | “ 内联 “ 机制避免内存开销 - 将使用 Lambda 表达式作为参数的函数定义为内联函数 | 内联函数本质 - 宏替换 )相关的知识,希望对你有一定的参考价值。
文章目录
一、内联函数
1、Lambda 表达式弊端
Lambda 表达式弊端 :
Lambda 表达式 的 灵活使用 , 是以 牺牲内存开销为代价的 ;
在 Java 虚拟机中 , Lambda 表达式 是以 实例对象 的形式 , 存储在堆内存中的 , 这就产生了内存开销 ;
2、" 内联 " 机制避免内存开销
" 内联 " 机制避免内存开销 :
在 Kotlin 语言中提供了一种 " 内联 " 机制 ,
解决了上面的 Lambda 表达式的 内存开销 问题 ,
将 使用 Lambda 表达式 作为参数的函数 定义为 inline 内联函数 ,
Java 虚拟机就 不会再为 lambda 表达式 在堆内存中 创建 实例对象 了 ,
这样就 避免了 Lambda 表达式 的内存开销 ;
3、内联函数本质 - 编译时宏替换
内联函数使用 :
在使用 Lambda 表达式的时候 ,
Kotlin 编译器直接将 inline 内联函数 的 函数体 直接拷贝到 使用位置 ;
内联函数 类似于 C 语言中的 预编译指令 宏定义 , 在编译时直接替换拷贝宏定义内容 ;
Kotlin 中的 内联函数 也是一种 编译时 进行 宏替换的操作 ;
4、内联函数不能递归
内联函数不能递归 :
如果 将函数 定义为 内联函数 ,
则该函数 不能进行递归操作 ,
递归操作 会导致 函数体的 无限复制粘贴 ,
编译器会报警 ;
二、普通函数代码示例
代码示例 : 下面的代码中 studentDoSomething
是普通函数 ;
fun main()
// 定义函数类型变量, 之后作为函数参数传递给函数
val actionFun = name: String, age: Int ->
"student $name $age years old, say hello"
// 调用 studentDoSomething 函数, 输入姓名, 年龄, 执行的操作
studentDoSomething("Tom", 18, actionFun);
fun studentDoSomething(name: String, age: Int,
action: (String, Int) -> String)
val act = action(name, age);
println(act)
将字节码转换为 Java 代码内容如下 :
import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = 1, 1, 16,
bv = 1, 0, 3,
k = 2,
d1 = "\\u0000\\u001c\\n\\u0000\\n\\u0002\\u0010\\u0002\\n\\u0002\\b\\u0002\\n\\u0002\\u0010\\u000e\\n\\u0000\\n\\u0002\\u0010\\b\\n\\u0000\\n\\u0002\\u0018\\u0002\\n\\u0000\\u001a\\u0006\\u0010\\u0000\\u001a\\u00020\\u0001\\u001a0\\u0010\\u0002\\u001a\\u00020\\u00012\\u0006\\u0010\\u0003\\u001a\\u00020\\u00042\\u0006\\u0010\\u0005\\u001a\\u00020\\u00062\\u0018\\u0010\\u0007\\u001a\\u0014\\u0012\\u0004\\u0012\\u00020\\u0004\\u0012\\u0004\\u0012\\u00020\\u0006\\u0012\\u0004\\u0012\\u00020\\u00040\\b¨\\u0006\\t",
d2 = "main", "", "studentDoSomething", "name", "", "age", "", "action", "Lkotlin/Function2;", "KotlinDemo"
)
public final class HelloKt
public static final void main()
Function2 actionFun = (Function2)null.INSTANCE;
studentDoSomething("Tom", 18, actionFun);
// $FF: synthetic method
public static void main(String[] var0)
main();
public static final void studentDoSomething(@NotNull String name, int age, @NotNull Function2 action)
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(action, "action");
String act = (String)action.invoke(name, age);
boolean var4 = false;
System.out.println(act);
三、内联函数代码示例
代码示例 : 下面的代码中 studentDoSomething
是内联函数 ;
fun main()
// 定义函数类型变量, 之后作为函数参数传递给函数
val actionFun = name: String, age: Int ->
"student $name $age years old, say hello"
// 调用 studentDoSomething 函数, 输入姓名, 年龄, 执行的操作
studentDoSomething("Tom", 18, actionFun);
inline fun studentDoSomething(name: String, age: Int,
action: (String, Int) -> String)
val act = action(name, age);
println(act)
将字节码转换为 Java 代码内容如下 :
import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = 1, 1, 16,
bv = 1, 0, 3,
k = 2,
d1 = "\\u0000\\u001c\\n\\u0000\\n\\u0002\\u0010\\u0002\\n\\u0002\\b\\u0002\\n\\u0002\\u0010\\u000e\\n\\u0000\\n\\u0002\\u0010\\b\\n\\u0000\\n\\u0002\\u0018\\u0002\\n\\u0000\\u001a\\u0006\\u0010\\u0000\\u001a\\u00020\\u0001\\u001a3\\u0010\\u0002\\u001a\\u00020\\u00012\\u0006\\u0010\\u0003\\u001a\\u00020\\u00042\\u0006\\u0010\\u0005\\u001a\\u00020\\u00062\\u0018\\u0010\\u0007\\u001a\\u0014\\u0012\\u0004\\u0012\\u00020\\u0004\\u0012\\u0004\\u0012\\u00020\\u0006\\u0012\\u0004\\u0012\\u00020\\u00040\\bH\\u0086\\b¨\\u0006\\t",
d2 = "main", "", "studentDoSomething", "name", "", "age", "", "action", "Lkotlin/Function2;", "KotlinDemo"
)
public final class HelloKt
public static final void main()
Function2 actionFun = (Function2)null.INSTANCE;
String name$iv = "Tom";
int age$iv = 18;
int $i$f$studentDoSomething = false;
String act$iv = (String)actionFun.invoke(name$iv, Integer.valueOf(age$iv));
boolean var5 = false;
System.out.println(act$iv);
// $FF: synthetic method
public static void main(String[] var0)
main();
public static final void studentDoSomething(@NotNull String name, int age, @NotNull Function2 action)
int $i$f$studentDoSomething = 0;
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(action, "action");
String act = (String)action.invoke(name, age);
boolean var5 = false;
System.out.println(act);
以上是关于Kotlin函数 ⑦ ( 内联函数 | Lambda 表达式弊端 | “ 内联 “ 机制避免内存开销 - 将使用 Lambda 表达式作为参数的函数定义为内联函数 | 内联函数本质 - 宏替换 )的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin系列之letwithrunapplyalso函数的使用
Kotlin 协程Flow 异步流 ⑦ ( 调用 FlowCollector#emit 发射元素时自动执行 Flow 流的取消检测 | 启用检测 Flow 流的取消cancellable函数 )
Kotlin 协程Flow 异步流 ⑦ ( 调用 FlowCollector#emit 发射元素时自动执行 Flow 流的取消检测 | 启用检测 Flow 流的取消cancellable函数 )