Kotlin中,两个Boolean表达式可以使用and
连接,也可以使用&&
连接,那么他们的区别是什么呢?
现象
示例一
val args = arrayOf<String>()
when {
args.isNotEmpty() && (args[0].toLowerCase() == "sender") -> {
println("This is a sender")
}
args.isNotEmpty() && (args[0].toLowerCase() == "receiver") -> {
println("This is a receiver")
}
else -> {
println("This is nothing")
}
}
输出
This is nothing
示例二
val args = arrayOf<String>()
when {
args.isNotEmpty() and (args[0].toLowerCase() == "sender") -> {
println("This is a sender")
}
args.isNotEmpty() and (args[0].toLowerCase() == "receiver") -> {
println("This is a receiver")
}
else -> {
println("This is nothing")
}
}
输出
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
结论
使用
&&
连接两个表达式时,会从左往右依次判定每个表达式的结果,当遇到某个表达式的结果为false
时,则会直接返回整个表达式的结果为false
,不会再执行接下来的表达式。使用
and
连接两个表达式时,会执行所有的表达式并收集结果,最后把and
两边的结果再做逻辑与操作得出最终结果。
分析
and
是kotlin类的一个方法,很多类都可以拥有这个方法,而and
表达式两边如果都是Boolean的时候,则调用的是Boolean
的and
实现。它的定义如下:
public class Boolean private constructor() : Comparable<Boolean> {
......
public infix fun and(other: Boolean): Boolean
......
}
所以可以看出,表达式中and
左边是Boolean
类自己,and
右边是输入此方法的参数other
。
- 对于表达式中
and
左边的子表达式,要调用Boolean
的and
方法,必须要先把左边的子表达式变成一个对象后才能调用此对象的and
,所以左边的子表达式会被执行。 - 对于表达式中
and
右边的子表达式,需要先被变成一个Boolean
对象后才能被传入and
方法中,所以右边的子表达式会被执行。 - 最终在
and
方法中对and
左右两边的表达是结果求值后返回才作为表达式最终的结果。
这就是为什么用and
连接两个表达式时,两个表达式都会被执行的原因。
延伸
同理,or
与||
会有同样的效果。