[Kotlin] and与&&的区别

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的时候,则调用的是Booleanand实现。它的定义如下:

public class Boolean private constructor() : Comparable<Boolean> {
        ......

        public infix fun and(other: Boolean): Boolean

        ......
}

所以可以看出,表达式中and左边是Boolean类自己,and右边是输入此方法的参数other

  • 对于表达式中and左边的子表达式,要调用Booleanand方法,必须要先把左边的子表达式变成一个对象后才能调用此对象的and,所以左边的子表达式会被执行。
  • 对于表达式中and右边的子表达式,需要先被变成一个Boolean对象后才能被传入and方法中,所以右边的子表达式会被执行。
  • 最终在and方法中对and左右两边的表达是结果求值后返回才作为表达式最终的结果。

这就是为什么用and连接两个表达式时,两个表达式都会被执行的原因。

延伸

同理,or||会有同样的效果。

推荐阅读更多精彩内容