理想情况下,我认为注释掉的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.");
}
}