inline

inline 关键字的用处:高阶函数(Higher-order Functions)有它们天然的性能缺陷,我们通过 inline 关键字让函数用内联的方式进行编译,来减少参数对象的创建,从而避免出现性能问题。

所以,inline 是用来优化的吗?是,但你不能无脑使用它,你需要确定它可以带来优化再去用它,否则可能会变成负优化。其实换个角度想想:既然 inline 是优化,为什么 Kotlin 没有直接开启它,而要把它做成选项,而且还是个默认关闭的选项?就是因为它还真不一定是优化,加不加它需要我们自己去做判断。那怎么去做这个判断呢?很简单,如果你写的是高阶函数,会有函数类型的参数,加上 inline 就对了。

noinline

当一个函数被内联之后,它内部的那些函数类型的参数就不再是对象了,因为它们的壳被脱掉了。换句话说,对于编译之后的字节码来说,这个对象根本就不存在。一个不存在的对象,你怎么使用?

所以当你要把一个这样的参数当做对象使用的时候,Android Studio 会报错,告诉你这没法编译:

那……我如果真的需要用这个对象怎么办?加上 noinline:

加了 noinline 之后,这个参数就不会参与内联了:

那我们就也可以正常使用它了。

所以,noinline 的作用是什么?是用来局部地、指向性地关掉函数的内联优化的。既然是优化,为什么要关掉?因为这种优化会导致函数中的函数类型的参数无法被当做对象使用,也就是说,这种优化会对 Kotlin 的功能做出一定程度的收窄。而当你需要这个功能的时候,就要手动关闭优化了。这也是 inline 默认是关闭、需要手动开启的另一个原因:它会收窄 Kotlin 的功能。

那么,我们应该怎么判断什么时候用 noinline 呢?很简单,比 inline 还要简单:你不用判断,Android Studio 会告诉你的。当你在内联函数里对函数类型的参数使用了风骚操作,Android Studio 拒绝编译的时候,你再加上 noinline 就可以了。

CrossInline

Kotlin 制定了一条规则:Lambda 表达式里不允许使用 return,**除非——**这个 Lambda 是内联函数的参数。

那这样的话规则就简单了:

  1. Lambda 里的 return,结束的不是直接的外层函数,而是外层再外层的函数;
  2. 但只有内联函数的 Lambda 参数可以使用 return。

本来在调用处最后那行的 return 是要结束它外层再外层的 main() 函数的,但现在因为它被放在了 runOnUiThread() 里,hello() 对它的调用就变成了间接调用。所谓间接调用,直白点说就是它和外层的 hello() 函数之间的关系被切断了。和 hello() 的关系被切断,那就更够不着更外层的 main() 了,也就是说这个间接调用,导致 Lambda 里的 return 无法结束最外面的 main() 函数了。

这就表示什么?当内联函数的 Lambda 参数在函数内部是间接调用的时候,Lambda 里面的 return 会无法按照预期的行为进行工作。

这就比较严重了,因为这造成了 Kotlin 这个语言的稳定性的问题了。结果是不可预测的,这能行吗,是吧?

那怎么办?

Kotlin 的选择依然是霸气一刀切:内联函数里的函数类型的参数,不允许这种间接调用。

解决了!解决不了问题,我就解决提出问题的人。

那我如果真的有这种需求呢?如果我真的需要间接调用,怎么办?使用 crossinline。

crossinline 也是一个用在参数上的关键字。当你给一个需要被间接调用的参数加上 crossinline,就对它解除了这个限制,从而就可以对它进行间接调用了:

Kotlin inline noinline crossline相关推荐

  1. Kotlin 中infix,inline,noinline,crossinline ,refied 等的理解

    1. infix 的作用 infix 标示的函数可以使用中缀表示法, 中缀表示法就是在写法上可以忽略 . 与 ()并且必须满足三个条件 必须是成员函数或者扩展函数 必须只有一个参数 其参数不能有可变参 ...

  2. 学习Kotlin(五)函数与Lambda表达式

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  3. Kotlin学习笔记28 Flow part2 Flow引入 Flow的执行 取消 构建器 中间操作符 终端操作符 默认执行顺序 上下文相关

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 1  一个方法返回多个结果各种实现 /*** 一个方法返回多个结果* 方式1 返回一个集合* 特点* 1 方法本身是阻塞的 ...

  4. kotlin内联函数_Kotlin内联函数,参数化

    kotlin内联函数 In this tutorial, we'll be looking into Kotlin inline function. We'll follow that with Re ...

  5. Kotlin骚气写法 三

    文章目录 ViewGroup获取ChildView集合 inline noinline crossinline比较 Kotlin 简化 Parcelable orEmpty() kotlin 代理 关 ...

  6. Kotlin Language

    Kotlin 相比 Java 有哪些优点 Kotlin 完全兼容 Java Kotlin 更简洁 去掉了语句结尾的分号 支持扩展方法.操作符重写.头等函数 & 高阶函数.支持 Lambda 表 ...

  7. Kotlin基础学习(1)

    Kotlin基础学习(1) 本文主要讲解kotlin的部分基础知识,并不是全部基础. 提示:纯属个人理解,如有理解错误,欢迎留言指正批评. 一.Null检查机制 kotlin对于声明可为空的参数,使用 ...

  8. 你知道台湾Android开发面試題是什么样的吗?

    前言 想要成為一名優秀的Android開發,你需要一份完備的 知識體系,在這裏,讓我們一起成長為自己所想的那樣~. 金九银十是大家的換工作潮 在這波浪潮裡沉浮的我 經歷過快一個月的面試後,決定把這些遇 ...

  9. 浅谈那些你不知道的C艹语法

    C艹实践中的超神语法 pragma 卡常必备QAQ #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(" ...

最新文章

  1. 结构化场景中的RGB-D SLAM
  2. java简单线程池实例代码
  3. 有必要学python吗-让孩子学Python编程有必要吗
  4. linux ora 00119,ORA-00119和ORA-00132的解决方案
  5. jQuery中的动画理论干货
  6. 解决sublime text 3使用Install Package时出现There are no packages available for installation问题
  7. Datatable转实体 实体转换辅助类
  8. 前端笔记之Vue(五)TodoList实战拆分store跨域练习代理跨域
  9. JavaScript43种常见的浏览器兼容性问题大汇总
  10. rollup函数(分组后对每组数据分别合计)
  11. 随机打乱数据的几种方式
  12. 『杭电1888』Rectangular Polygons
  13. redis优化,bigkey,hotkey,配置优化,缓存雪崩、缓存穿透、缓存击穿
  14. 7 个热门又优质的小程序 UI 组件库,社区、电商、工具各类都有!
  15. Java Date类获取当前年月日
  16. LVGL打印LOG日志
  17. jenkins 安装 SVN Publisher 后向 svn 提交代码报错: E170001: Authentication required for...
  18. 201512683信息检索知识
  19. linux 命令行下wlan无线网卡配置 2
  20. 【03173】2020年10月高等教育自学考试-软件开发工具

热门文章

  1. Idea开发maven插件
  2. 移动端CAD版本转换如何输出DXF格式?
  3. 第35篇-某众点评字体CSS加密分析
  4. docker for windows--Windows 10 家庭中文版 21H2 安装Docker Desktop初体验
  5. 浙江天搜科技股份有限公司发起“春节X计划”话题,邀你一起讨论如何过一个温暖春节...
  6. win10 dcom服务器进程占用cpu,win10DCOM进程及资源管理CPU占用过高导致主机卡顿
  7. 蚂蚁金融科技全面开放战略背后的技术布局 1
  8. Android修改充电图片,安卓充电提示音修改教程
  9. 结合Vue的相关知识进行温度转换
  10. mysql 学习笔记