Kotlin-内联函数
来源:互联网 发布:2017淘宝流量突然下降 编辑:程序博客网 时间:2024/06/03 17:10
概述
在说内联函数之前,先说说函数的调用过程。
调用某个函数实际上将程序执行顺序转移到该函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。这种转移操作要求在转去前要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保存地址继续执行。也就是通常说的压栈和出栈。因此,函数调用要有一定的时间和空间方面的开销。那么对于那些函数体代码不是很大,又频繁调用的函数来说,这个时间和空间的消耗会很大。
那怎么解决这个性能消耗问题呢,这个时候需要引入内联函数了。内联函数就是在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来直接进行替换。显然,这样就不会产生转去转回的问题,但是由于在编译时将函数体中的代码被替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间代销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。
inline
在Kotlin中,使用inline修饰符标记内联函数,既会影响到函数本身, 也影响到传递给它的Lambda表达式,这两者都会被内联到调用处。
例如:
inline fun lock<T>(lock: Lock, body: () -> T): T {// ...}
编译器可以直接产生下面的代码, 而不必为参数创建函数对象, 然后再调用这个参数指向的函数:
l.lock()try { foo()}finally { l.unlock()}
noinline
如果一个内联函数的参数中有多个 Lambda 表达式, 而你只希望内联其中的一部分, 你可以对函数的一部分参数添加 noinline 标记:
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { // ...}
可内联的 Lambda 表达式只能在内联函数内部调用, 或者再作为可内联的参数传递给其他函数, 但noinline 的 Lambda 表达式可以按照我们喜欢的方式任意使用: 可以保存在域内, 也可以当作参数传递, 等等。
非局部返回(Non-local return)
在Kotlin中, 使用无限定符的通常的return语句, 只能用来退出一个有名称的函数, 或匿名函数. 这就意味着, 要退出一个Lambda表达式, 我们必须使用一个 标签, 无标签的 return 在 Lambda 表达式内是禁止使用的, 因为 Lambda 表达式不允许强制包含它的函数返回:
fun foo() { ordinaryFunction { return // 错误: 这里不允许让 `foo` 函数返回 }}
如果 Lambda 表达式被传递去的函数是内联函数, 那么 return 语句也可以内联, 因此 return 是允许的。
fun foo() { inlineFunction { return // OK: 这里的 Lambda 表达式是内联的 }}
注:
有些内联函数可能并不在自己的函数体内直接调用传递给它的 Lambda 表达式参数, 而是通过另一个执行环境来调用, 比如通过一个局部对象, 或者一个嵌套函数. 这种情况下, 在 Lambda 表达式内, 非局部的控制流同样是禁止的. 为了标识这一点, Lambda 表达式参数需要添加 crossinline修饰符。
inline fun f(crossinline body: () -> Unit) { val f = object: Runnable { override fun run() = body() } // ...}
- Kotlin-内联函数
- Kotlin基础教程-内联函数
- Kotlin-内联函数
- Kotlin 第十六章:内联函数
- Kotlin的inline内联函数
- Kotlin-23.内联函数(Inline Functions)
- Kotlin学习之-6.3 内联函数
- kotlin学习笔记——内联函数
- Kotlin函数与Lambdas(三)--- 内联函数
- Kotlin语法(十九)-内联函数(Inline Functions)
- Kotlin Reference (十六) 函数和lambda表达式:内联函数、内联属性
- Kotlin内联:noinline与crossinline
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- Shell脚本基础3-获取用户输入
- Linux: Problems with Fedora 25 and the Wayland window manager
- Android 应用安装过程分析
- Java基础——HashMap源码分析及面试题解答
- width:100%与width:auto的区别
- Kotlin-内联函数
- Ubuntu开发环境搭建(5)【Android-JNI开发环境 (windows10+ubuntu16.04)】
- [杂言] 坑集合(Finished!)
- 刷清橙OJ--A1028.选择计算
- 非常详细的rsyslogd & logrotate配置文件解析
- APP开发实战173-ActionBar资源文件的生成工具
- android -简单注册登录页面应用
- 排序--选择排序
- 提高篇项目1-将数组n前面的数输出