当前位置: 首页 > article >正文

kotlin知识体系(四) : inline、noinline、crossinline 关键字对应编译后的代码是怎样的 ?

1. inline、noinline、crossinline 的作用

在 Kotlin 里,inlinenoinlinecrossinline 这几个关键字和高阶函数紧密相关,它们能够对高阶函数的行为进行优化和控制。本文接下来会详细介绍它们的作用和原理。

1.1 inline 关键字

inline 关键字用于修饰高阶函数,其作用是在编译时将函数调用处替换为函数体本身,以此避免函数调用的开销,提高代码的执行效率。

1.1.1 示例代码
// 定义一个内联高阶函数
inline fun inlineFunction(block: () -> Unit) {block()
}fun main() {inlineFunction {println("This is an inline function call.")}
}
1.1.2 代码解释

在上述示例中,inlineFunctioninline 关键字修饰。在编译时,inlineFunction 的调用会被替换为函数体内容,这样就不会有额外的函数调用开销。不过,使用 inline 也会使生成的字节码体积增大,因为函数体被复制到了调用处。

1.2 noinline 关键字

当高阶函数被 inline 修饰时,它的所有函数参数默认也会被内联。要是你不希望某个函数参数被内联,就可以使用 noinline 关键字。

1.2.1 示例代码
// 定义一个内联高阶函数,包含一个 noinline 参数
inline fun mixedFunction(inlineBlock: () -> Unit, noinline noInlineBlock: () -> Unit) {inlineBlock()noInlineBlock()
}fun main() {mixedFunction({ println("This is an inline block.") },{ println("This is a non - inline block.") })
}
1.2.2 代码解释

在这个例子中,mixedFunction 是内联函数,inlineBlock 会被内联,而 noInlineBlock 由于使用了 noinline 关键字,不会被内联。noinline 通常用于需要将函数参数存储在变量中或者作为其他函数的返回值的情况。

1.3 crossinline 关键字

在使用 inline 修饰高阶函数时,内联函数参数里不允许有非局部返回(即从外层函数返回)。若需要在 Lambda 表达式中使用 return 语句,但又不想使用 noinline 来避免内联,就可以使用 crossinline 关键字。

1.3.1 示例代码
// 定义一个内联高阶函数,包含一个 crossinline 参数
inline fun crossInlineFunction(crossinline block: () -> Unit) {val wrapper = {block()}wrapper()
}fun main() {crossInlineFunction {// 这里不能使用 return 进行非局部返回,但可以执行其他操作println("Inside crossinline block.")}
}
1.3.2 代码解释

在这个例子中,crossInlineFunction 是内联函数,block 参数使用了 crossinline 关键字。在 block 中不能使用非局部返回,但可以正常执行其他操作。这样既能保证参数被内联,又能在一定程度上控制返回行为。

综上所述,inlinenoinlinecrossinline 关键字在 Kotlin 中用于控制高阶函数及其参数的内联行为,有助于优化代码性能和控制函数返回逻辑。

2.对应编译后的代码是怎样的 ?

下面通过具体示例,详细分析 Kotlin 中 inlinenoinlinecrossinline 关键字在编译后代码的表现。

2.1 inline 关键字

2.1.1 Kotlin 代码示例
inline fun inlineFunction(block: () -> Unit) {println("Before block")block()println("After block")
}fun main() {inlineFunction {println("Inside block")}
}
2.1.2 编译后代码分析

在编译时,inline 函数会被内联展开。上述代码编译后,大致等效于以下 Java 代码(Kotlin 编译成 JVM 字节码,这里用 Java 形式便于理解):

public class Main {public static void main(String[] args) {System.out.println("Before block");System.out.println("Inside block");System.out.println("After block");}
}

inlineFunction 的函数体直接替换了调用处的代码,避免了函数调用的开销。

2.2 noinline 关键字

2.2.1 Kotlin 代码示例
inline fun mixedFunction(inlineBlock: () -> Unit, noinline noInlineBlock: () -> Unit) {inlineBlock()noInlineBlock()
}fun main() {mixedFunction({ println("Inline block") },{ println("Noinline block") })
}
2.2.2 编译后代码分析

inlineBlock 会被内联展开,而 noInlineBlock 不会。编译后的代码大致如下:

public class Main {private static final class NoInlineBlock implements Function0<Unit> {public Unit invoke() {System.out.println("Noinline block");return Unit.INSTANCE;}}public static void main(String[] args) {System.out.println("Inline block");NoInlineBlock noInlineBlock = new NoInlineBlock();noInlineBlock.invoke();}
}

inlineBlock 被内联到调用处,而 noInlineBlock 被封装成一个实现了 Function0 接口的类,通过创建对象并调用 invoke 方法来执行。

2.3 crossinline 关键字

2.3.1 Kotlin 代码示例
inline fun crossInlineFunction(crossinline block: () -> Unit) {val wrapper = {block()}wrapper()
}fun main() {crossInlineFunction {println("Crossinline block")}
}
2.3.2 编译后代码分析

crossinline 保证了 Lambda 表达式不会有非局部返回,但仍然会被内联。编译后的代码大致如下:

public class Main {public static void main(String[] args) {final class Wrapper implements Function0<Unit> {public Unit invoke() {System.out.println("Crossinline block");return Unit.INSTANCE;}}Wrapper wrapper = new Wrapper();wrapper.invoke();}
}

block 被内联到 wrapper 中,同时由于 crossinline 的存在,避免了非局部返回的问题。

总结来说,inline 关键字使函数体在调用处展开,noinline 阻止特定函数参数内联,crossinline 允许内联的同时限制非局部返回,这些关键字在编译后的代码中体现了不同的处理方式。

相关文章:

kotlin知识体系(四) : inline、noinline、crossinline 关键字对应编译后的代码是怎样的 ?

1. inline、noinline、crossinline 的作用 在 Kotlin 里&#xff0c;inline、noinline 和 crossinline 这几个关键字和高阶函数紧密相关&#xff0c;它们能够对高阶函数的行为进行优化和控制。本文接下来会详细介绍它们的作用和原理。 1.1 inline 关键字 inline 关键字用于修…...

JavaScript 手写 call、apply、bind 和 new

1. 手写 call 方法 核心思路&#xff1a;改变函数的 this 指向并立即执行&#xff0c;通过将函数临时挂载到目标对象上调用。 Function.prototype.myCall function (context, ...args) {// 如果 context 为 null 或 undefined&#xff0c;则默认为 windowcontext context |…...

睡眠健康领域的智能硬件设备未来的发展趋势

随着社会节奏的不断加快&#xff0c;人们的睡眠问题愈发多了起来&#xff0c;主要表现有以下几个方面&#xff1a; 睡眠质量下降 浅睡眠增多&#xff1a;现代生活中&#xff0c;人们面临着各种压力源&#xff0c;如工作压力、生活琐事、经济压力等&#xff0c;这些压力会导致大…...

计算机网络基础:量子通信技术在网络中的应用前景

计算机网络基础:量子通信技术在网络中的应用前景 一、前言二、量子通信技术基础2.1 量子通信的基本概念2.2 量子通信的主要原理2.2.1 量子密钥分发(QKD)原理2.2.2 量子隐形传态原理三、量子通信技术的特点3.1 绝对安全性3.2 超高通信速率潜力3.3 抗干扰能力强四、量子通信技…...

Postman 下载文件指南:如何请求 Excel/PDF 文件?

在 Postman 中进行 Excel/PDF 文件的请求下载和导出&#xff0c;以下是简明的步骤&#xff0c;帮助你轻松完成任务。首先&#xff0c;我们将从新建接口开始&#xff0c;逐步引导你完成整个过程。 Postman 请求下载/导出 excel/pdf 文件教程...

Stereolabs ZED Box Mini:机器人与自动化领域的人工智能视觉新选择

在人工智能视觉技术快速发展的今天&#xff0c;其应用场景正在持续拓宽&#xff0c;从智能安防到工业自动化&#xff0c;从机器人技术到智能交通&#xff0c;各领域都在积极探索如何利用这一先进技术。而 Stereolabs 推出的ZED Box Mini&#xff0c;正是一款专为满足这些多样化…...

arm之s3c2440的I2C的用法

基础概念 IC&#xff08;Inter-Integrated Circuit&#xff09;又称I2C&#xff0c;是是IICBus简称&#xff0c;所以中文应该叫集成电路总线。 IIC的总线的使用场景&#xff0c;所有挂载在IIC总线上的设备都有两根信号线&#xff0c;一根是数据线SDA&#xff0c;另一 根是时钟…...

安装node,配置npm, yarn, pnpm, bun

文章目录 安装node, 配置 npm, yarn, pnpm, bun配置node配置 npm, yarn, pnpm, bunnpmyarnpnpmbun 安装node, 配置 npm, yarn, pnpm, bun 配置node ​ 输入网址&#xff1a;Node.js&#xff0c;包含各种安装方式以及多版本管理方式。也可以直接下载安装包。 安装包的安装过程…...

redis部署架构

一.redis多实例 如上图所示&#xff0c;我们经常使用实例的端口号来作为实例的安装目录名称。 1.创建实例安装目录 如上图所示&#xff0c;这是创建实例的安装目录&#xff0c; 2.拷贝实例的配置文件 如上图所示&#xff0c;将redis解压目录下的配置文件拷贝到对应的conf目录…...

深入理解指针(4)(C语言版)

文章目录 前言一、回调函数是什么&#xff08;一&#xff09;定义&#xff08;二&#xff09;工作原理&#xff08;三&#xff09;应用场景 二、qsort举例&#xff08;一&#xff09;qsort函数简介&#xff08;二&#xff09;比较函数的定义&#xff08;三&#xff09;使用示例…...

【HTML】验证与调试工具

个人主页&#xff1a;Guiat 归属专栏&#xff1a;HTML CSS JavaScript 文章目录 1. HTML 验证工具概述1.1 验证的重要性1.2 常见 HTML 错误类型 2. W3C 验证服务2.1 W3C Markup Validation Service2.2 使用 W3C 验证器2.3 验证结果解读 3. 浏览器开发者工具3.1 Chrome DevTools…...

【Mysql】SQL 优化全解析

文章目录 一、理解执行计划​1.1 执行计划的作用​1.2 查看执行计划​ 二、查询优化​2.1 避免全表扫描​2.2 使用覆盖索引​2.3 合理使用 JOIN​ 三、索引优化​3.1 索引设计原则​3.2 索引维护​ 在数据驱动的当今时代&#xff0c;MySQL 作为应用广泛的开源关系型数据库&…...

​​SenseGlove与Aeon Robotics携手推出HEART项目,助力机器人培训迈向新台阶

在自动化和机器人技术快速发展的今天&#xff0c;SenseGlove和Aeon Robotics联合推出了一项创新项目——HEART项目。该项目在欧盟资助的MasterXR框架内展开&#xff0c;旨在通过整合虚拟现实&#xff08;VR&#xff09;、力反馈触觉手套&#xff08;SenseGlove项目Rembrandt&am…...

mapbox进阶,仿照百度,加载marker点位,移入marker点切换图标,点击展示气泡,气泡和marker联动

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️marker 标注点位 api1.3.1 ☘️构造函数…...

使用HTML5和CSS3实现3D旋转相册效果

使用HTML5和CSS3实现3D旋转相册效果 这里写目录标题 使用HTML5和CSS3实现3D旋转相册效果项目介绍技术栈核心功能实现思路1. HTML结构2. CSS样式解析2.1 基础样式设置2.2 3D效果核心样式2.3 卡片样式 3. JavaScript交互实现3.1 旋转控制3.2 自动播放功能 技术要点总结项目亮点总…...

HTML5 新的 Input 类型学习笔记

HTML5 引入了多种新的表单输入类型&#xff0c;这些新特性不仅增强了输入控制&#xff0c;还提供了更强大的验证功能&#xff0c;使表单设计更加灵活和便捷。以下是 HTML5 新的 Input 类型的详细学习笔记。 一、color 类型 功能&#xff1a;用于选取颜色。 使用场景&#xff…...

游戏引擎学习第186天

回顾并规划今天的任务 现在&#xff0c;我们站在了一个关键的时刻&#xff0c;准备突破&#xff0c;拥有一些优秀的性能分析代码。从目前来看&#xff0c;我们已经能够看到时间的消耗情况&#xff0c;我对这一点感到非常兴奋。昨天的直播中我们勉强让一些东西工作了&#xff0…...

NDK CMake工程中引入其他C++三方库

在Android NDK CMake工程中引入其他C三方库时&#xff0c;有以下几种常见的依赖方式&#xff1a; 1. 源码依赖 如果三方库的源代码包含在你的项目目录中&#xff0c;并且它有自己的CMake配置&#xff0c;可以使用add_subdirectory将三方库的构建过程集成到你的项目中。 示例…...

【redis】持久化之RDB与AOF

在数字世界的脉搏中&#xff0c;数据是流淌的血液&#xff0c;而持久化则是保障系统生命力的核心机制。作为内存数据库的标杆&#xff0c;Redis凭借其高性能特性成为互联网架构的基石&#xff0c;但其「易失性」的天然属性也催生了关键命题&#xff1a;如何在服务重启或故障时保…...

Brainstorm绘制功能连接图(matlab)

上篇笔记简单介绍了Brainstorm&#xff0c;本次使用Brainstorm绘制功能连接图。而对于连接矩阵&#xff0c;软件中有几种方法&#xff1a;相关、相干、双变量格兰杰因果关系、相位锁相值、包络相关、相位转移熵。 首先&#xff0c;对数据进行预处理&#xff0c;保存为.set&…...

华为HG532路由器RCE漏洞 CVE-2017-17215 复现

华为HG532路由器RCE漏洞 CVE-2017-17215 CVE-Description Huawei HG532 with some customized versions has a remote code execution vulnerability. An authenticated attacker could send malicious packets to port 37215 to launch attacks. Successful exploit could l…...

CSS3学习教程,从入门到精通,CSS3 弹性盒子(Flexbox)布局全面指南(20)

CSS3 弹性盒子(Flexbox)布局全面指南 一、Flexbox 概述 Flexbox&#xff08;弹性盒子&#xff09;是 CSS3 提供的一种一维布局模型&#xff0c;可以轻松实现各种复杂的页面布局。它特别适合处理不同屏幕尺寸下的元素排列和对齐问题。 主要优势&#xff1a; 简单实现垂直居中…...

Redis 性能数据解读与问题排查优化版

目录标题 Redis 性能数据解读与问题排查优化版一、Redis 性能数据解读二、常见问题排查与解决&#xff08;一&#xff09;CPU 使用率高&#xff08;二&#xff09;内存使用异常&#xff08;三&#xff09;集群状态异常&#xff08;四&#xff09;数据库状态问题 三、综合优化建…...

新能源动力电池测试设备深度解析:充放电设备与电池模拟器的差异及技术趋势

一、技术原理对比与核心技术创新 充放电设备 核心原理与硬件架构 充放电设备的核心功能是通过电力电子技术精确控制电池的充放电过程&#xff0c;其硬件架构包括高精度电源模块、双向DC/DC变换器、数据采集系统和温控单元。例如&#xff0c;在放电阶段&#xff0c;设备通过双向…...

LVS的三种工作模式简述

一、引言 在过去的十几年中&#xff0c;Internet从几个研究机构相连为信息共享的网络发展成为拥有大量应用和服务的全球性网络&#xff0c;它正成为人们生活中不可缺少的 一部分。虽然Internet发展速度很快&#xff0c;但建设和维护大型网络服务依然是一项挑战性的任务&#xf…...

Ribbon负载均衡的深度解析与应用

在微服务架构中&#xff0c;服务之间的调用频繁且复杂&#xff0c;因此负载均衡显得尤为重要。Spring Cloud生态系统中&#xff0c;Ribbon作为一个客户端负载均衡器&#xff0c;扮演着关键的角色。它不仅能提高系统的响应速度&#xff0c;还能确保系统的稳定性和可用性。接下来…...

使用 Layers 扩展你的 Nuxt4 应用

面对一个臃肿的页面或项目&#xff0c;你会如何简化重构、扩展它&#xff1f; 当单个 Vue 文件中界面/业务足够多时&#xff0c;通常我们会把它拆分成多个 components 或 composables 来引入&#xff0c;以此来减少此文件复杂度和增加可维护性。 当一个项目的界面/业务逻辑足…...

Excel处理控件Aspose.Cells指南:如何在不使用 Microsoft Excel 的情况下解锁 Excel 工作表

Microsoft Excel 允许用户使用密码保护工作表&#xff0c;以防止未经授权的更改。但是&#xff0c;在某些情况下&#xff0c;您可能需要在不使用 Microsoft Excel 的情况下解锁 Excel 工作表。在本指南中&#xff0c;我们将探讨解锁 Excel 工作表的不同方法&#xff0c;例如使用…...

进军场景智能体,云迹机器人又快了一步

&#xff08;图片来源&#xff1a;Pixels&#xff09; 2025年&#xff0c;AI和机器人行业都发生了巨大改变。 数科星球原创 作者丨苑晶 编辑丨大兔 2025年&#xff0c;酒店行业正掀起一股批量采购具备AI功能的软硬一体解决方案的热潮。 在DeepSeek、Manus等国产AI软件的推动…...

vue 使用v-model实现父子组件传值——子父组件同步更新

基于vue2和vue3两个版本的框架略显不同&#xff0c;所以我分开的来讲&#xff1a; 1、vue2 子组件&#xff08;my-input.vue&#xff09;&#xff1a; <template><input type"text" :value"name" input"inputChange" /> </tem…...