If statement 是什么使得安全呼叫(问号)的解释与经典if不同?
在Kotlin中,如果我们将一个类成员声明为var和nullable类型,编译器将不允许我们运行成员函数,尽管我们在调用函数之前放置了if语句,因为编译器不能保证在检查null之后和调用方法之前,该成员没有被设置为null。 但是如果我们使用的是安全调用,编译器会批准我们的代码。 我的问题是,编译器如何使安全调用原子化?在示例中,不是第二个线程可以在检查null和调用eat方法之间更改变量吗? 第一种情况的代码:If statement 是什么使得安全呼叫(问号)的解释与经典if不同?,if-statement,kotlin,nullable,kotlin-null-safety,If Statement,Kotlin,Nullable,Kotlin Null Safety,在Kotlin中,如果我们将一个类成员声明为var和nullable类型,编译器将不允许我们运行成员函数,尽管我们在调用函数之前放置了if语句,因为编译器不能保证在检查null之后和调用方法之前,该成员没有被设置为null。 但是如果我们使用的是安全调用,编译器会批准我们的代码。 我的问题是,编译器如何使安全调用原子化?在示例中,不是第二个线程可以在检查null和调用eat方法之间更改变量吗? 第一种情况的代码: class MyWolf { var w : Wolf?
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
if (w != null)
{
w.eat()
}
}
}
class Wolf
{
fun eat() : Unit
println("wolf is eating")
}
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
w?.eat()
}
}
class Wolf
{
fun eat():Unit
{
//code
}
}
第二种情况的代码:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
if (w != null)
{
w.eat()
}
}
}
class Wolf
{
fun eat() : Unit
println("wolf is eating")
}
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
w?.eat()
}
}
class Wolf
{
fun eat():Unit
{
//code
}
}
编译器将字段的内容放入局部变量,然后将其与null进行比较。如果反编译Kotlin字节码,您可以清楚地看到它。编译器将字段的内容放入局部变量,然后将其与null进行比较。如果反编译Kotlin字节码,您可以清楚地看到它。这是否回答了您的问题?因为我不明白答案,我不能说:这回答了你的问题吗?因为我不明白答案,我不能说:好的。很高兴知道。不幸的是,我不知道如何阅读bytecode@Eitanos30它创建了许多嵌套的ifs。在每个if中,它计算下一个值,将其放入局部变量,并与null进行比较。@Eitanos30对于Kotlin字节码-很容易从Android Studio查看并将其反编译为可读性更高的Java。只需转到工具->Kotlin->显示Kotlin字节码并按DecompileRaspopv,当说将字段内容放入局部变量时,您的意思是将对象的副本保存到局部变量中吗?@Eitanos30它不创建副本,只是将对同一对象的引用放入局部变量。确定。很高兴知道。不幸的是,我不知道如何阅读bytecode@Eitanos30它创建了许多嵌套的ifs。在每个if中,它计算下一个值,将其放入局部变量,并与null进行比较。@Eitanos30对于Kotlin字节码-很容易从Android Studio查看并将其反编译为可读性更高的Java。只需转到工具->Kotlin->显示Kotlin字节码并按DecompileRaspopv,当说将字段内容放入局部变量时,您的意思是将对象的副本保存到局部变量中吗?@Eitanos30它不创建副本,只是将对同一对象的引用放入局部变量中。