Kotlin 中的 crossinline 和 noinline 有什么区别?

2024-04-09

  1. 这段代码编译时有警告 (性能影响微不足道):

    inline fun test(noinline f: () -> Unit) {
        thread(block = f)
    }
    
  2. 这段代码不编译 (非法使用内联参数):

    inline fun test(crossinline f: () -> Unit) {
        thread(block = f)
    }
    
  3. 这段代码编译时有警告 (性能影响微不足道):

    inline fun test(noinline f: () -> Unit) {
        thread { f() }
    }
    
  4. 这段代码编译时没有警告或错误:

    inline fun test(crossinline f: () -> Unit) {
        thread { f() }
    }
    

这是我的问题:

  • 为什么 (2) 不能编译而 (4) 可以编译?
  • 到底有什么区别noinline and crossinline?
  • 如果 (3) 没有产生性能改进,为什么 (4) 会产生性能改进呢?

来自内联函数参考 https://kotlinlang.org/docs/reference/inline-functions.html:

请注意,某些内联函数可能会调用作为参数传递给它们的 lambda,而不是直接从函数体直接调用,而是从另一个执行上下文(例如本地对象或嵌套函数)调用。在这种情况下,lambda 中也不允许非本地控制流。为了表明这一点,lambda 参数需要使用 crossinline 修饰符进行标记

因此,示例 2. 无法编译,因为crossinline仅强制执行本地控制流,并且表达式block = f违反了这一点。示例 1 可以编译,因为noinline不需要这样的行为(显然,因为它是一个普通的函数参数)。

示例 1 和 3 不会产生任何性能改进,因为唯一的 lambda 参数被标记为noinline,渲染inline函数的修饰符无用且多余 - 编译器想要内联某些内容,但所有可能的内容都已标记为不内联。

考虑两个函数,A and B

A

inline fun test(noinline f: () -> Unit) {
    thread { f() }
}

B

fun test(f: () -> Unit) {
    thread { f() }
}

功能A行为类似于函数B从某种意义上说,参数f不会被内联(B函数没有内联函数体test而在A功能、身体:thread { f() }仍然被内联)。

现在,在示例 4 中情况并非如此,因为crossinline f: () -> Unit范围can被内联,它只是不能违反前面提到的非局部控制流规则(比如为全局变量分配新值)。如果它可以被内联,编译器就会假设性能得到改进,并且不会像示例 3 中那样发出警告。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kotlin 中的 crossinline 和 noinline 有什么区别? 的相关文章

随机推荐

  • atom-typescript 抱怨 tsconfig.json——我怎样才能自动创建一个?

    我刚刚开始使用此处引用的 atom typescript 插件 TypeScript 入门 http basarat gitbooks io typescript content docs getting started html 该页面指
  • Access VBA随机改变大小写

    我在 MS Access 中有一个编码项目 有一些开发人员编码并将源代码签入 SVN 服务器 由于 SVN 服务器用于管理代码 因此它可以识别源代码文件中的更改 这些源代码文件中存在问题 VBA经常改变大小写字母 但我们不知道为什么 当我进
  • 反思 ExpandoObject

    我写了一个漂亮的函数 它将接受system object 反映其属性并将对象序列化为 JSON 字符串 它看起来像这样 public class JSONSerializer public string Serialize object o
  • Android 指纹删除后密钥失效

    我正在 7 1 1 上的 Google Pixel 设备上进行测试 发现从设备中删除所有指纹后 我的私钥并未失效 我已经根据演示应用程序使用单个对称 SecretKey 进行了测试 并且按预期工作 但是使用非对称密钥对只会引发KeyPerm
  • React Hooks:用于模式事件监听器的 useEffect

    我有一个模式对话框 如果用户在模式之外单击 我想关闭该对话框 我编写了以下 useEffect 代码 但遇到了以下问题 模式对话框包含许多子项 React Nodes 这些子项可能会发生变化 例如 用户删除列表中的条目 这些交互触发我的 o
  • 滑动动画存在多个视图同步问题

    我正在尝试用两个文本视图制作动画 两者都处于相对布局中 动画的功能是左文本视图会向左移动一点 同时右文本视图也会向左移动一点 我努力了 http nineoldandroids com http nineoldandroids com an
  • 发布配置文件未在 TFS Build 上部署

    我在 VS2012 中有一个 net4 解决方案 它有一个带有自己的发布配置文件的网站 当从 VS 中执行时 配置文件成功通过 webdeploy 发布 但当使用 TFS2012 构建时 它似乎被忽略 我将这些 MSBuild 参数传递到构
  • 如何在IOS中制作月亮绕地球旋转并同时自己旋转的CAAnimation效果?

    我知道在IOS中创建月亮绕地球转的效果很简单 假设月球是一个 CALayer 对象 只需将该对象的锚点更改为地球 它就会以动画方式围绕地球旋转 但如何创造出同时自转的月亮呢 由于月亮只能有一个锚点 看来我无法再让这个 CALayer 对象自
  • ViewPager Fragment 再次重新加载时消失

    以下是布局 test xml
  • 如何检查线段和从与水平面成一定角度的点发出的线射线之间的交点?

    给定一条线段 即两个点 x1 y1 和 x2 y2 一个点 P x y 和一个角度 theta 我们如何判断这条线段和从 P 发出的 与水平方向成 角的线射线是否相交 如果它们相交 如何找到交点 我们来标记点q x1 y1 and q s
  • 替换现有的 Outlook 日历约会

    我正在与icalndar约会一代做一些工作 这将允许代表查看活动的网站并单击提供的链接将约会添加到他们的日历中 我有一个工作程序集 它将根据一组已知的信息 开始日期 结束日期 标题等 生成 ics 格式的输出 作为物理文件或流 我为日历约会
  • 方法声明应与 PHP 中的父方法兼容

    Strict Standards Declaration of childClass customMethod should be compatible with that of parentClass customMethod PHP 中
  • 避免 InvalidOperationException 的最佳实践:集合已修改?

    很多时候我需要这样的东西 foreach Line line in lines if line FullfilsCertainConditions lines Remove line 这不起作用 因为我总是得到一个InvalidOperat
  • Highcharts 系列更新动画

    我可以使用此方法更新蜘蛛图的数据值并查看其动画 chart series i setData newSeries i data 但是 由于蜘蛛图中的系列不仅包括data还有其他领域 例如 series name Allocated Budg
  • 如何在容器内放置旋转图像?

    使用 CSS3 HTML 如果需要的话还可以使用 javascript jquery 我需要将图像旋转 90 270 度并使其位置填充其父 div 容器 听起来很简单 但是当图像旋转时 位置会发生变化 我不知道如何或为什么 这是一个 jsF
  • 仅当某个字符不直接跟在另一个特定字符之后时才拆分该字符串

    我有以下代码行来分割字符串data2出现空白实例时进入列表 string list data2 split 但是 在我的一些数据中 日期格式为 28 Dec 这里 上面的代码在我不希望的情况下在日期和月份之间的空白处进行了分割 有没有办法我
  • Haskell 中的融合是什么?

    我时不时地注意到 Haskell 文档中的以下内容 例如在Data Text https hackage haskell org package text 1 2 2 1 docs Data Text html 受融合影响 What is
  • Ruby 是否有与未定义实例变量等效的 method_missing ?

    当我调用一个不存在的方法时 method missing会告诉我方法的名称 当我尝试访问尚未设置的变量时 该值只是nil 我试图动态拦截对 nil 实例变量的访问 并根据正在访问的变量的名称返回一个值 最接近的等价物是 PHP 的 get
  • J2ME - 使用 javax.microedition.amms.control.camera.CameraControl;是否可以禁用快门声音?

    在我的黑莓应用程序中 我已经实现了相机 并希望用我自己的声音替换默认的快门声音 我想我可以通过使用方法enableShutterFeedback false 来静音默认相机声音 然后播放我自己的声音 或者在相机激活之前立即播放我的声音来做到
  • Kotlin 中的 crossinline 和 noinline 有什么区别?

    这段代码编译时有警告 性能影响微不足道 inline fun test noinline f gt Unit thread block f 这段代码不编译 非法使用内联参数 inline fun test crossinline f gt