Kotlin:检查 if 语句中的可为空值是否有效



理想情况下,我认为注释掉的if语句更有意义,至少对我来说是这样。我的意思是,如果有人问我 null 是否大于 0,我会回答否。或者,如果 null 为真,则也不为真。但是这些并没有像我预期的那样工作,并且抛出了编译错误。所以,我像下面这样改变了那些。但这些看起来并不好或简洁。有没有更好的方法来处理这些问题?

class Result(val code:Int)
{
}
fun getResult():Result?
{
return null;
}
fun main(args: Array<String>)
{
var result = getResult();
var success:Boolean? = null;
//if(result?.code > 0)
if(result?.code?:0 > 0)
{
print("Good.");
}
//if(success)
if(success == true)
{
print("Good.");
}
}

>被编译为compareTo(other: Int)调用,按照惯例工作(它定义为Int上的operator)。但是,您无法在可为空的Int?上调用此函数。

有一个解决方法:在Int?上创建另一个扩展:

operator fun Int?.compareTo(other: Int): Int =
(this ?: 0).compareTo(other)

现在您的通话确实有效:

if (result?.code > 0)
print("Good.")

可为空的元素实际上是Result实例本身,而不是其code属性。

我认为将let与 safe-get 运算符结合使用的结果更准确地反映了代码的设计:

result?.let {
if(it.code > 0) {
}
}

注释掉的代码未编译的原因是result?.code可为空,并且您不能在可为空的表达式上调用比较运算符(即在这种情况下>),因为它们不键入匹配。(它被定义为仅接受不可为空的类型)

如果 null 大于 0,那么我会回答"否"。或者如果 null 为真,则也不为

Kotlin 完全消除了可为空和不可为空实体之间的歧义。因此,在编译时,如果您将某些内容与可为空的类型进行比较,kotlin 编译器会拒绝编译,以避免提前出现运行时异常。在爪哇中,

Integer x = null;
System.out.println(x > `)

这会编译,但在运行时抛出NullPointerException,这显然是您不希望的。Kotlin 编译器在这里只是很聪明,通过拒绝编译来避免此类运行时异常。

现在说到更好的处理方式,就像大家说的,用let是合适的办法。更简单的方法是定期检查 if expesion

if(result != null && result.code > 0) {
print("Good.");
}
result?.code > 0

它不起作用,因为>内部调用compareTo()方法。compareTo()方法不适用于可为 null 的对象。这就是为什么你必须在变量code上添加elvisoperator(?:) 以分配一个值,如果code变量为 null。这样该值就不为 null,然后compareTo()方法就可以工作了。

result?.code?:0 > 0

我添加了一个要解决let。如果result不为 null,那么我们将在let块中执行代码。请检查更新的代码。

class Result(val code:Int){
}
fun getResult():Result?{
return null;
}
fun main(args: Array<String>){
var result = getResult();
var success:Boolean? = null;
//if(result?.code > 0)
if(result?.code?:0 > 0){
print("Good.");
}
// Updated Code        
result?.let{
if(result.code > 0)
print("Good.")
}
//if(success)
if(success == true){
print("Good.");
}
}

最新更新