Kotlin 中的Inline函数

在这里插入图片描述

Kotlin 中的Inline内联函数是一个很有价值的工具,可以显着提高代码的性能和可读性。通过消除函数调用的开销,内联函数可以实现更快的执行和更好的优化。在本文中,我们将深入了解内联函数的世界,探索它们在 Kotlin 编程中的好处和实际应用。无论您是初学者还是经验丰富的开发人员,了解如何利用内联函数无疑将提高您的编码效率。
通过“inlining”函数代码,Kotlin 减少了与函数调用相关的开销,从而提高了性能。这就像拥有一位高效的助手,可以预测您的需求、与您一起工作并简化整个流程。内联函数为您的代码带来了这种级别的效率和优化,从而实现更快的执行和更简化的开发体验。
— 我们创建的每个高阶函数都会导致新的对象创建和内存分配。
fun main() {
    someHighOrderFunction {
        println(it)
    }
}

fun someHighOrderFunction(someLambda: (String) -> Unit) {
    someLambda("")
}

查看反编译的 Kotlin 字节代码:

在这里插入图片描述
在这里插入图片描述

现在,假设您想在 for 循环中使用这个简单的函数,该函数有数千次迭代。它会创建那么多新实例,这在性能方面会造成混乱。
让我们将 inline 关键字添加到我们的高阶函数中,并再次查看字节码:

在这里插入图片描述

以下是 inline 函数的一些特殊之处:

  • Inline函数允许非本地返回以及本地返回。
  • Inline函数无法访问周围类或作用域中的私有变量和方法,除非将它们声明为公共或内部(内部的应使用 @PublishedApi 进行标记)。
  • Inline函数应主要用于短函数,通常由 2-3 行代码组成,因为它们使用反射。虽然反射很有用,但它会显着影响性能。

crossinline 和 noinline 关键字

有一些有用的关键字与Inline互补。

Crossinline

Crossinline 关键字是遍历两个高阶函数作用域的帮助器(一个是Inline函数,另一个不是Inline函数)。通常,当我们在Inline函数内部使用非内联高阶函数时,我们不允许在非Inline的 lambda 范围内使用Inline函数的 lambda,为了保持这一目的,我们可以使用 crossinline 关键字在Inline函数的 lambda 之前:
inline fun someHighOrderFunction(someLambda: (String) -> Unit) {

    anotherHigherOrderFunction {
        someLambda("") //This is not allowed. ⚠️⚠️
    }
}

fun anotherHigherOrderFunction(anotherLambda:() -> Unit) {
    anotherLambda()
}
将 crossinline 关键字添加到我们的 someLambda 参数中:
inline fun someHighOrderFunction(crossinline someLambda: (String) -> Unit) {
    someLambda("")

    anotherHigherOrderFunction {
        someLambda("") //This works fine ✅✅
    }
}

fun anotherHigherOrderFunction(anotherLambda:() -> Unit) {
    anotherLambda()
}
这样做的原因是利用inline函数,我们可以使用非本地返回,这对于非inline函数(在本例中是我们的 anotherHighOrderFunction() )是不合适的,因为编译器会抱怨这种情况那 :
无法在此处inline“someLambda”:它可能包含非本地返回。将“crossinline”修饰符添加到参数声明“someLambda”

Noinline

当用 inline 关键字标记一个函数时,默认情况下它的所有 lambda 参数都是inline的,但在某些情况下(例如考虑到相关 lambda 中包含严厉代码的可能性),我们不希望inline特定的 lambda。然后,我们使用 noinline 关键字:
fun main() {
    someHighOrderFunction(
        someLambda = { },
        heavyHandedLambda = {
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
            println("")
        }
    )
}

inline fun someHighOrderFunction(someLambda: (String) -> Unit, noinline heavyHandedLambda: () -> Unit) {
    someLambda("")
    heavyHandedLambda()
}
您不希望该范围直接复制到您的调用站点中。特别是当您在循环中使用或在项目的每个部分中使用它时。

结论

Kotlin 中的inline函数提供了宝贵的好处,包括改进的性能和增强的代码可读性。通过消除函数调用开销,它们优化了执行速度并简化了开发。与高阶函数一起使用时,inline特别有利,可以防止每次调用时创建对象和分配内存。此外,“crossinline”关键字允许在inline函数和非inline函数之间遍历作用域,而“noinline”关键字则允许控制内联哪些 lambda。需要注意的是,inline内联函数对于短函数(通常由 2-3 行代码组成)最有效,并且由于反射对性能的影响,应谨慎使用。总的来说,利用inline函数可以极大地提高 Kotlin 项目中的代码效率。

快乐编码。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐