可以说我有以下课程:
class MyClass {
private var username: String? = null
private var projectName: String? = null
private var buildNumber: Int = -1
private val presenter: Presenter = Presenter()
fun present() {
username = ""
projectName = ""
if (username != null && projectName != null && buildNumber != -1) {
presenter.viewReady(this, username, projectName, buildNumber)
} else {
throw Exception("You did something bad!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我收到错误Smart cast to 'String' is impossible, because 'username' is a mutable property that could have been changed by this time?
这与不是线程安全有关吗?
基于null安全文档,我认为这适用于1.中的任何一个,username并且projectName在它们作为params使用的相同函数中设置2.并且它们作为params的使用被包装在if语句中检查它们的值.
Kotlin编译器不能同时证明另一个线程username或者projectName被另一个线程突变.私有领域也没有帮助,因为反思可能绕过这一点.
相关文档属于Type Checks and Casts:
请注意,当编译器无法保证变量在检查和使用之间无法更改时,智能强制转换不起作用.更具体地说,智能演员表适用于以下规则:
- val局部变量 - 总是;
- val属性 - 如果属性是私有属性或内部属性,或者在声明属性的同一模块中执行检查.智能模型不适用于具有自定义getter的开放属性或属性;
- var局部变量 - 如果在检查和使用之间没有修改变量,并且没有在修改它的lambda中捕获;
- var属性 - 从不(因为变量可以在任何时候被其他代码修改).
而是在局部变量中捕获属性引用.
他们作为params的用法包含在if语句中检查它们的值.
Kotlin中的if语句不会"捕获"一个属性.当您声明包含属性的if语句并在块内再次访问它时,编译器可能会为您进行智能转换.但是访问规则仍然相同 - getter将被调用两次.