我读过this question篇,但我有一个关于crossinline关键词的更基本的问题.我真的不确定它解决了什么问题,以及它是如何解决的.

From 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:

[Emphasis added]

This statement is ambiguous to me. 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.

第二,短语"表明",可以有多种解读方式.表明什么?a particular case美元是不允许的?这是允许的吗?给定函数定义中的非局部控制流是(或不)允许的?

简而言之,我很难弄清楚使用这个关键词的真正背景是什么,使用它与客户沟通的内容是什么,以及应用这个关键词的预期结果是什么.

推荐答案

首先,我很难真正理解"此类 case "的含义.我对这个问题有一个大致的了解,但不能给出一个很好的例子.

下面是一个示例:

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'.
    }
}

Here, the function that is passed to someInterfaceBy { ... } is inlined inside an anonymous class implementing SomeInterface. Compilation of each call-site of someInterfaceBy produces a new class with a different implementation of someFunction().

To see what could go wrong, consider a call of someInterfaceBy { ... }:

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

在内联lambda中,是return is non-local,实际上是return from 101.但是,由于lambda没有被调用并且泄漏到对象ireturn from 101中,因此可能是完全没有意义的:如果在foo已经返回之后或者甚至在不同的线程中调用i.someFunction()(从而也是lambda),该怎么办?

一般来说,'such cases'指的是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函数打算将其函数参数内联到某个地方,而不是调用in-place,而是存储并在以后调用,inline函数的参数应该标记为crossinline,表示此处传递的lambda中不允许非本地控制流.

Kotlin相关问答推荐

Kotlin协程挂起继续线程

可以从背景图像中点击图标吗?

Scala性状线性化等价于Kotlin

如何使用Kotlinx.LocalDateTime获取重置时间为00:00的当前日期?

使函数同时挂起和取消挂起

通过快捷键手动砍掉功能参数等

Kotlin中反射中Int到可空Double的隐式转换失败

如何使用 Android CameraX 自动对焦

OnClickListener 未在 ConstraintLayout 上触发

参考 Kotlin 中的 Java 接口静态字段

在 kotlin 中写入 parcer 可空值

将 jetpack compose 添加到现有元素

以编程方式重新启动 Spring Boot 应用程序/刷新 Spring 上下文

将多个 Kotlin 流合并到一个列表中,而无需等待第一个值

Kotlin not nullable值可以为null吗?

类型不匹配:推断类型为 LoginActivity 但应为 LifecycleOwner

lateinit 的 isInitialized 属性在伴随对象中不起作用

访问Kotlin中的属性委托

Android Jetpack Compose 中的文本渐变

比较Kotlin的NaN