Kotlin-inline函数特效

在 Kotlin 里,inline 关键字主要用于内联函数与内联属性。下面为你详细介绍:

内联函数

使用 inline 关键字修饰的函数,在编译时,编译器会把函数调用处替换成函数体本身,而不是常规的函数调用过程。这样做的好处是能减少函数调用的开销,特别是在使用高阶函数时效果显著。和C语言的宏替换有殊途同归。

Kotlin 复制代码
    @Test
    fun main3() {
        inlineFun {
            println("hello")
        }
    }


    private inline fun inlineFun(call: () -> Unit) {
        call.invoke()
    }
代码解释
  • 当 inlineFun 被调用时,编译器会直接把 inlineFun 的函数体插入到调用处,避免了函数调用的开销。
  • 内联函数特别适合与 Lambda 表达式配合使用,因为 Lambda 表达式会带来额外的对象创建和调用开销,使用内联函数可以消除这些开销。
noinline

若内联函数里包含多个 Lambda 表达式参数,而你不希望所有的 Lambda 表达式都被内联,可以使用 noinline 关键字修饰不需要内联的 Lambda 表达式。

复制代码
inline fun multipleLambda(block1: () -> Unit, noinline block2: () -> Unit) {
    block1()
    block2()
}

适用场景

  • 高阶函数:当函数接收 Lambda 表达式作为参数时,使用内联函数可以避免 Lambda 表达式带来的额外开销。
  • 频繁调用的小函数:对于一些经常被调用且函数体较小的函数,使用内联函数可以提高性能。

注意事项

  • 内联函数会增加生成代码的大小,因为函数体被复制到每个调用处。所以,对于函数体较大的函数,不建议使用内联。
  • 内联函数不能包含非局部返回,除非 Lambda 表达式被标记为 crossinline

非局部返回限制

  • 默认情况:内联函数中的 Lambda 表达式可以使用非局部返回(也就是直接从包含该 Lambda 表达式的函数中返回)。不过,这也带来了一定的限制。例如下面的代码:

    fun main() {
    inlineFunction {
    println("执行 Lambda 表达式")
    return // 这里会直接从 main 函数返回
    }
    println("这行代码不会被执行")
    }

    inline fun inlineFunction(block: () -> Unit) {
    block()
    }

  • crossinline 修饰符 :若不希望 Lambda 表达式中出现非局部返回,可以使用 crossinline 修饰符。示例如下:

    inline fun inlineFunction(crossinline block: () -> Unit) {
    val anotherBlock = {
    block()
    }
    anotherBlock()
    }

    fun main() {
    inlineFunction {
    println("执行 Lambda 表达式")
    // return // 这里使用 return 会报错,因为 block 被 crossinline 修饰
    }
    println("这行代码会被执行")
    }

类型参数限制

内联函数的类型参数不能用作实际类型。也就是说,不能在运行时获取内联函数类型参数的实际类型。例如:

复制代码
inline fun <T> printType() {
    // 这里不能获取 T 的实际类型
    // println(T::class)  // 这样写会报错
}

4. 不支持私有和内部函数

内联函数通常不能是私有或内部函数(除非它们是在类内部定义的,并且只在该类内部使用)。因为内联函数的代码会被复制到调用处,私有和内部函数的访问限制在这种情况下会变得难以处理。

5. 递归调用限制

内联函数不适合进行递归调用。因为内联函数会在编译时展开,如果进行递归调用,会导致代码无限膨胀,最终可能会导致编译错误或生成非常大的代码文件。例如:

复制代码
inline fun recursiveInlineFunction(n: Int): Int {
    return if (n == 0) 1 else n * recursiveInlineFunction(n - 1)
}
相关推荐
2501_915921435 分钟前
iOS 实时日志怎么看?KeyMob 的日志过滤、崩溃报告与符号化
android·ios·小程序·https·uni-app·iphone·webview
染指11106 分钟前
157.Agent-LangGraph-工具(实现ReAct Agent模式)
开发语言·人工智能·python·langchain·agents
千里马学框架14 分钟前
Service服务绑定对进程adj影响及常见绑定错误
android·智能手机·性能优化·程序员·framework·性能·安卓失业
程序猿乐锅15 分钟前
【从0-1学习Python | 第九篇】继承
开发语言·后端·python·学习·fastapi
wdfk_prog21 分钟前
lwip教程 38:从 `lwipopts.h` 到 Port Contract——lwIP 裁剪、构建选择、OS Port 与 Network Port
java·开发语言
开开心心就好24 分钟前
证件照排版打印工具,免费可自定义尺寸
服务器·开发语言·算法·随机森林·pdf·音视频·散列表
我是高手高手高高手31 分钟前
宝塔 PHP多版本,切换PHP默认版本
开发语言·php
CodeYp201931 分钟前
第16讲:set 和 map 的使用
开发语言·c++·set·map
物联网老王33 分钟前
第05篇-Agent 连不上工具?MCP 就是那根“USB-C”
开发语言·人工智能·ai·aigc·ai编程
2601_966949658 小时前
如何根据研究的起止时间截取分钟级行情?Python 实战与 QuantDash 数据处理指南
开发语言·python·pandas·量化交易·1024程序员节·股票数据·quantdash