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

理想情况下,我认为评论性的陈述更有意义,至少对我而言。 我的意思是,如果有人问我,如果null大于0,我会回答不。 或者如果null是真的,那么也没有。 但是那些没有按照我的预期工作,并抛出编译错误。 所以,我改变了下面这些。 但是那些看起来不好或简洁。 有没有更好的方法来处理这些?

class Result(val code:Int) { } fun getResult():Result? { return null; } fun main(args: Array) { 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."); } } 

注释掉的代码没有被编译的原因是因为result?.code是可以为空的,所以你不能在可空的expression式上调用比较运算符(即>在这种情况下),因为它们没有types匹配。 (它被定义为只接受不可为空的types)

如果null大于0,比我会回答不。 或者如果null是真的,那么也没有

Kotlin在可空和不可空的实体之间完全消除歧义。 因此,在编译时,如果您正在与可空types进行比较,kotlin编译器会拒绝编译,以免提前发生运行时exception。 在java中,

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

这编译但在运行时抛出一个NullPointerException ,你显然不想要。 Kotlin编译器只是在这里很聪明,通过拒绝编译来避免这种运行时exception。

现在,以更好的方式来处理它,就像大家所说,使用let是一个合适的方法。 一个简单的方法可以是一个普通的空检查,如果expresion

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

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

我认为使用let结合safe-get操作符对结果更准确地反映了代码的设计:

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

>被编译为compareTo(other: Int)的调用,按惯例工作(在Int定义为operator )。 你不能在可空Int?上调用这个函数Int? 虽然。

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

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

现在你的电话确实工作:

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

它不工作,因为>内部调用compareTo()方法。 compareTo()方法在可空对象上不起作用。 这就是为什么你必须在variablescode上添加elvis运算符( :)以便在codevariables为空时分配一个值。 所以值不为null,然后compareTo()方法起作用。

 result?.code?:0 > 0 

我已经添加了一个let解决。 如果result不是null,那么我们将执行let块内的代码。 请检查更新的代码。

 class Result(val code:Int){ } fun getResult():Result?{ return null; } fun main(args: Array){ 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."); } }