Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 在闭包中使用var局部变量如何防止编译器对此变量执行智能转换?_Kotlin_Casting_Closures - Fatal编程技术网

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

Kotlin 在闭包中使用var局部变量如何防止编译器对此变量执行智能转换?,kotlin,casting,closures,Kotlin,Casting,Closures,在闭包中使用var局部变量如何防止编译器执行智能强制转换 我读到如果我们在闭包中使用local(var)变量,那么它就不再是智能可转换的,因为现在它有点像一个属性:它可以从其他地方修改,因此编译器不能再保证它的类型 有人能举例说明这种情况吗?如果您有一个界面: interface Callback { fun onEvent() } 然后,在函数中,如果创建修改函数中局部变量的接口实现,则该变量将被接口捕获 fun myFunction() { var x: Int? = 4

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

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


有人能举例说明这种情况吗?

如果您有一个界面:

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的这个问题,这些lambda只能立即使用,至少我认为应该这样。合同仍然是一项实验性功能,它似乎无法防止这种特殊的智能转换错误。

首先,谢谢:)其次,我几乎理解最后一行
val y=2*x
之外的所有代码,应该在这里进行哪种转换?我认为smart cast只与
is
as
语句相关?此外,编译器没有足够的智能来检查在检查时刻和使用变量时刻之间是否有对某个函数的调用,该接口作为参数?智能转换也适用于空检查<代码>?:返回为空检查。由于如果变量为null,它将从函数返回,因此对于未捕获的非null变量,它将能够将其从
Int?
智能转换为
Int
。是的,编译器不够聪明,无法看到您没有对捕获它的函数或接口执行任何操作。但是没有理由创建这样的接口或函数,所以这并不重要。@Tenfoud04,谢谢——再次:)但是检查?:return,多长时间相关?因为在?:return和val y=2*x之间,x可以被设置为null,如果您将其设置为null,编译器会看到它,因此在您更改它的代码行之后,null检查不再适用。这是假设它没有被捕获。