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运算符( ? :)以便在code
variables为空时分配一个值。 所以值不为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."); } }