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

  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) 编译?
  • noinlinecrossinline到底有什么区别?
  • 如果 (3) 没有产生任何性能改进,为什么 (4) 会这样做?

最佳答案

来自 inline functions reference :

Note that some inline functions may call the lambdas passed to them as parameters not directly from the function body, but from another execution context, such as a local object or a nested function. In such cases, non-local control flow is also not allowed in the lambdas. To indicate that, the lambda parameter needs to be marked with the crossinline modifier

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

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

考虑两个函数,AB

一个

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 参数 可以 内联,所以它不能违反上述非-local 控制流规则(例如为全局变量分配新值)。如果它可以被内联,编译器会假设性能得到提升,并且不会像示例 3 中那样发出警告。

https://stackoverflow.com/questions/38827186/

相关文章:

kotlin - 如何在 Kotlin 中迭代 hashmap?

generics - kotlin 中的 out 关键字是什么

java - 将 Kotlin 数据对象映射到数据对象的更好方法

java - 如何将 Java 源文件的一部分转换为 Kotlin?

android - Kotlin - 将 List 转换为 MutableList 的最惯用方式

dictionary - Kotlin 是否有 Map 文字的语法?

kotlin - 如何从命令行运行 Kotlin 类?

kotlin - 如何在 Kotlin 中写入文件?

java - 在 Kotlin 中定义 log TAG 常量的最佳方法是什么?

kotlin - 在 Android Studio 中构建时如何解决错误 "Failed to re