Kotlin 的 crossinline 关键字

标签 kotlin

我已阅读 this question但我对 crossinline 关键字有一个更基本的问题。我不太确定它正在解决什么问题以及它是如何解决的。

来自 the Kotlin Docs ,

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:

[强调添加]

这句话对我来说是模棱两可的。首先,我很难想象“这种情况”是什么意思。我对问题所在有一个大致的了解,但无法举出一个很好的例子。

其次,短语“表明这一点”可以有多种读法。表明什么?那特殊情况是不允许的?它允许的吗?给定函数定义中的非本地控制流是否允许(或不允许)?

简而言之,我很难弄清楚使用 this 的真正上下文是什么,使用它与客户交流什么,以及应用这个关键字的预期结果是什么。

最佳答案

First, I am having trouble actually picturing what is meant by "such cases". I have a general idea of what the issue is but can't come up with a good example of it.

这是一个例子:

interface SomeInterface {
    fun someFunction(): Unit
}

inline fun someInterfaceBy(f: () -> Unit): SomeInterface { 
    return object : SomeInterface {
        override fun someFunction() = f() 
        //                            ^^^
        // Error: Can't inline 'f' here: it may contain non-local returns. 
        // Add 'crossinline' modifier to parameter declaration 'f'.
    }
}

这里,传递给 someInterfaceBy { ... } 的函数被内联在实现 SomeInterface 的匿名类中。 someInterfaceBy 的每个调用站点的编译都会生成一个新类,该类具有不同的 someFunction() 实现。

要查看可能出现的问题,请考虑调用 someInterfaceBy { ... }:

fun foo() {
    val i = someInterfaceBy { return }
    // do something with `i`
}

在内联 lambda 中,return is non-local实际上意味着foo返回。但是由于没有调用 lambda 并泄漏到对象 i 中,return from foo 可能绝对没有意义:如果 i.在 foo 已经返回或什至在不同的线程中调用 someFunction() (因此是 lambda)?

一般来说,'这样的情况' 是指 inline 函数,这些函数不是在它们自己的主体(实际上,即考虑其他内联函数)中而是在一些内部调用它们的函数参数他们声明的其他函数,例如在非内联 lambda 和匿名对象中。


Second, the phrase "To indicate that," can be read multiple ways. To indicate what? That a particular case is not allowed? That it is allowed? That non-local control flow in a given function definition is (or is not) allowed?

这正是我上面描述的问题在 Kotlin 语言设计中得到解决的方式:每当 inline 函数打算将其函数参数内联到某个无法就地调用的地方 但存储后调用,inline函数的参数应该标记为crossinline,表示在传递的lambda中不允许非本地控制流在这里。

关于Kotlin 的 crossinline 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45760817/

相关文章:

Spring Reactive MongoDB不保存文档

java - 错误与removeAt java arraylist android

Android - 带有 Rxkotlin 过滤器的 Kotlin Sealed 类

java - Kotlin 内联类在底层实现接口(interface)

kotlin - 为什么 kotlin 不支持 suspend operator fun getValue?

java - 如何仅将对象传递到决策表的ACTION部分?

使用泛型进行 Java 和 Kotlin 转换。失去类型安全

ios - compileKotlinIos 失败 - 找不到 stdlib

string - 是否有正则表达式可以切换字符串中的字符大小写?

arrays - Kotlin - 为自定义类对象初始化一个数组