当前位置: 首页 > 知识库问答 >
问题:

在闭包中使用var局部变量如何防止编译器对此变量进行智能强制转换?

常光明
2023-03-14

在闭包中使用var局部变量如何阻止编译器进行智能强制转换?

我读到如果我们在闭包中使用本地(var)变量,那么它不再是智能可转换的,因为现在它有点像一个属性:它可以从其他地方修改,所以编译器不能再保证它的类型。

有人能举个例子吗?

共有1个答案

邵飞鸿
2023-03-14

如果您有接口:

interface Callback {
    fun onEvent()
}

然后,在函数中,如果创建修改函数中局部变量的接口实现,则该变量将由接口捕获。

fun myFunction() {
    var x: Int? = 4
    val myCallback = object: Callback {
        override fun onEvent() {
            x = 5
        }
    }
    x ?: return
    val y = 2 * x // error, smart cast is impossible.
}

由于它被捕获,局部变量不再只是局部变量。修改它的接口可以传递给调用它并修改您捕获的变量的其他函数。由于编译器不知道如何使用接口,它将拒绝智能强制转换接口捕获的变量。

出于同样的原因,如果在lambda中修改变量也会被捕获。编译器不知道调用lambda的频率和时间。

对于仅立即使用的内联lambda,合约最终应该会解决这个问题,至少我认为应该如此。合约仍然是一个实验性功能,它似乎无法防止这种特定的智能强制转换错误。

 类似资料:
  • 为了简化我的真实用例,让我们假设我想在一个列表中找到最大的数字: 但是,编译失败并出现以下错误: 智能强制转换为“Int”是不可能的,因为“max”是一个由变化的闭包捕获的局部变量 为什么更改的闭包会阻止智能强制转换在此示例中起作用?

  • 问题内容: 我正在使用handlebars.js,我想开始对所有内容进行预编译,但是似乎找不到找到预编译部分的方法。我的大部分模板实际上都是局部的。我尝试将它们像常规模板一样对待,但是将它们作为部分模板调用是行不通的。 有什么方法可以预编译局部函数,或者从另一个模板中调用一个模板吗? 问题答案: 我找到了一个更好的方法:将所有的部分代码预编译为模板,然后在代码中使用它们之前,添加以下行: 改进之处

  • 问题内容: 在Objective-C中,我在构建设置->代码中使用的其他C标志中设置了一堆编译器标志。例如: 标志=> -DPortNumber = 1 在代码中,我能够通过 这在Swift中不起作用,而且我找不到答案。 问题答案: C编译器的标志定义了预处理器宏。Swift中没有预处理器宏。因此,如果您要执行以下操作: …你不能。Swift旨在使源代码在编译之前在语法上完整。如果您可以在构建时关

  • This forces Smarty to (re)compile templates on every invocation. This setting overrides $compile_check. By default this is disabled. This is handy for development and debugging. It should never be use

  • 我知道这个问题以前有人问过,但似乎没有解决方案。我正在尝试使用名为的int变量来跟踪的顶部可见项目,该变量通过将视图的标记(类型“Any”)转换为Int来填充:

  • 我在网上搜索声明局部变量的方法,偶然发现了这个Oracle页面。该页面谈到了使用关键字“VAR”。 我正在使用IntelliJ,我相信我正确地将我的项目设置为使用“VAR”,但它不能正常工作。你知道我做错了什么吗? 在项目语言水平上,我也尝试了10个但没有区别。