2016-10-08 28 views
3

对于这段代码,科特林迫使我来处理一个空检查的情况,而在它没有其他线路,尽管是同样的情况:为什么我被迫使用!在空检查的组合?

if (r1 == null && r2 == null) 
    throw IllegalArgumentException("All nulls!") 
else if (r1 == null) 
    return r2!!.reading // <----- I am forced to !! here 
else if (r2 == null) 
    return r1.reading // <----- The compiler does not complain in this line 

这是一个错误或功能?

+0

R1和R2丘壑行之有效? – IRus

+1

为什么通过消除过程检查非空值而不是直接检查非空值?例如'R2 .reading:??R1 .reading:??抛出IllegalArgumentException( “!所有空值”)' – mfulton26

+0

@ mfulton26了'if'的问题表达并不详尽,即不覆盖的情况下当两个'R1 '和'r2'不为空。所以,虽然你的建议在某些情况下可能有用,但在这种情况下,它并不等同。 – Ilya

回答

7

的科特林编译器不会做的方式逻辑推理你期望:“我已经检查了R1 == NULL和r2 == NULL,所以现在如果我只检查R1 == null,则必须认识到r2不为空“。它没有。你没有在该分支中检查r2,所以它没有看到它不是空的。

在第二种情况下,情况比较简单:if (r1 == null) { ... } else { ... }。不要紧,你在else里面有另一张支票;编译器会发现您位于if (x == null)检查的else分支中,并了解该值不为空。

有添加这种逻辑的open feature request,但是,它不是在科特林队的近期路线图。

+0

我明白了。我只会期待那些!在多线程环境中。 – PedroD

1

可以略微调整你if表达,所以它会使少检查,并有智能施法应用于r2

if (r1 == null) { 
    if (r2 == null) throw IllegalArgumentException("All nulls!") 
    return r2.reading 
} else if (r2 == null) { 
    return r1.reading 
} 
2

恕我直言,如果某些应用逻辑是互斥的。我倾向于使用when {}来声明性地表达全部条件,而不是使用if(...) else if(..) else来组成逻辑。

使用when{}指定由案件的全部条件的情况下可以帮助开发人员只专注于这对于调试和以后的变化更容易具体情况。

相比之下,if else条件迫使开发人员从上到下追踪,以获得对其他人阅读起来相对困难并且难以指出无法访问的代码的整体逻辑。

我遇到了一些复杂的if else代码,我要建一个真值表理解逻辑的整体的一部分。

回到问题。智能用的情况下:) when{}

实现1

val someReading = when { 
    r1 != null && r2 == null -> r1.reading 
    r1 == null && r2 != null -> r2.reading 
    else -> throw IllegalArgumentException("All nulls!") 
} 

实现2

val someReading = 
     r1?.reading 
     ?: r2?.reading 
     ?: throw IllegalArgumentException("All nulls!") 
+0

请注意,当“r1”和“r2”都不为空时,第一个实现会抛出,否则不应该抛出。第二个也不等于问题中的代码。 – Ilya

相关问题