美文网首页
几种语言的==、===和is比较

几种语言的==、===和is比较

作者: 景知育德 | 来源:发表于2022-03-10 13:53 被阅读0次

    在许多语言中,使用==来判断两个值是否相等。有些语言中还有is,但是意义各不相同,本文着重于介绍各语言中这些概念。

    Python

    双等号

    Python 中的==来比较两个值是否相等。例如:

    a = 5
    b = 5
    print(a == b) # True
    

    数值上的相等是显而易见的,那么对于对象呢?

    先以 Python 自带的 list 对象为例:

    a = [1, 2, 3]
    b = [1, 2, 3]
    print(a == b) # True
    

    Python 将会对 list 中的每个元素进行比较。对于类的实例,实际上是调用__eq__()方法来进行比较的。

    class DemoClass():
        def __init__(self, value):
            self.value = value
        def __eq__(self, other):
            return self.value == other.value
    
    instance_a = DemoClass(5)
    instance_b = DemoClass(5)
    print(instance_a == instance_b) # True
    

    is

    Python 中的 is 则表示是否是同一对象:

    对于简单的数字:

    a = 5
    b = 5
    print(a is b) # True
    

    但是对于对象:

    a = [1, 2, 3]
    b = [1, 2, 3]
    print(a is b) # Flase
    c = a
    print(a is c) # True
    

    其它

    Python 中还有 isinstance() 函数和 type() 函数,用以确定对象的类别。

    区别:

    • type() 不会认为子类是一种父类类型,不考虑继承关系。

    • isinstance() 会认为子类是一种父类类型,考虑继承关系。

    如果要判断两个类型是否相同推荐使用 isinstance()。

    下面引用菜鸟教程的例子:

    class A:
        pass
     
    class B(A):
        pass
     
    isinstance(A(), A)    # True
    type(A()) == A        # True
    isinstance(B(), A)    # True
    type(B()) == A        # False
    

    Java

    在上文的 Python 中,==用来判断值是否相等,is用来判断是否是同一个对象。而在 Java 中,==同时拥有以上两种含义。

    双等号

    ==对于基本数据类型,是比较值;对于引用数据类型,是比较是否是同一对象,或者说是比较堆内存地址

    对于基本类型,自然可以直接==。(但是 Java 是区分 int 和 Integer,double 和 Double 等的,要注意!)

        public static void main(String[] args) {
            int a = 5;
            int b = 5;
            System.out.println(a == b); // true
        }
    

    对于类的实例,则比较的是否是同一对象。

    class DemoClass {
        private final int value;
        public DemoClass(int value) {
            this.value = value;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            DemoClass instanceA = new DemoClass(5);
            DemoClass instanceB = new DemoClass(5);
            System.out.println(instanceA == instanceB); // false
            DemoClass instanceC = instanceA;
            System.out.println(instanceA == instanceC); // true
        }
    }
    

    equals()

    默认情况下,比较是否是同一对象,将上例中的instanceA == instanceB改为instanceA.equals(instanceB),仍然输出false

    class DemoClass {
        private final int value;
        public DemoClass(int value) {
            this.value = value;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            DemoClass instanceA = new DemoClass(5);
            DemoClass instanceB = new DemoClass(5);
            System.out.println(instanceA.equals(instanceB)); // false
        }
    }
    

    因此,我们需要重写(Override)equals()方法,来实现自定义的比较:

    class DemoClass {
        private final int value;
    
        public DemoClass(int value) {
            this.value = value;
        }
    
        @Override
        public boolean equals(Object object) {
            return this.value == ((DemoClass) object).value;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            DemoClass instanceA = new DemoClass(5);
            DemoClass instanceB = new DemoClass(5);
            System.out.println(instanceA.equals(instanceB)); // true
        }
    }
    

    不过上文这种重写并不优雅,工程中请勿这样使用。

    instanceof

    Java 中使用instanceof来比较一个对象是否是一个类的实例。

    DemoClass类定义如前文,不赘述。

        public static void main(String[] args) {
            DemoClass instanceA = new DemoClass(5);
            System.out.println(instanceA instanceof DemoClass); // true
        }
    

    我们把instanceA的静态类型从DemoClass改为Object,众所周知,DemoClass继承于Object

        public static void main(String[] args) {
            Object instanceA = new DemoClass(5);
            System.out.println(instanceA instanceof DemoClass); // true
        }
    

    但是这样输出的仍然是true

    Kotlin

    双等号

    首先是对于简单的数字,这种情况下,各语言的==都会是比较值的。

    fun main() {
        val a = 5
        val b = 5
        print(a == b) // true
    }
    

    Kotlin 的双等于号相当于 Java 的equals,这在比较两个字符串是否内容相同时很方便。

    在没有重写equals方法的情况:

    class DemoClass(private val value: Int)
    
    fun main() {
        val instanceA = DemoClass(5)
        val instanceB = DemoClass(5)
        println(instanceA == instanceB) // true
        val instanceC = instanceA
        println(instanceA == instanceC) // true
    }
    

    似乎是 Kotlin 会自动生成一个euqals方法,所以这里的instanceA == instanceBtrue

    重写了之后,就更加明了了。

    class DemoClass(private val value: Int) {
        override fun equals(other: Any?): Boolean {
            return value == (other as DemoClass?)!!.value
        }
    }
    
    fun main() {
        val instanceA = DemoClass(5)
        val instanceB = DemoClass(5)
        println(instanceA == instanceB) // true
        val instanceC = instanceA
        println(instanceA == instanceC) // true
    }
    

    三等号

    Kotlin 中有三等号===来判断是否是同一对象。

    class DemoClass(private val value: Int) {
        override fun equals(other: Any?): Boolean {
            return value == (other as DemoClass?)!!.value
        }
    }
    
    fun main() {
        val instanceA = DemoClass(5)
        val instanceB = DemoClass(5)
        println(instanceA === instanceB) // false
        val instanceC = instanceA
        println(instanceA === instanceC) // true
    }
    

    这里可以看出,instanceA == instanceBfalse,因为二者并非同一对象。

    is

    Kotlin 中的 is 类似于 Python 中的 isinstance、Java 中的instanceof

    fun main() {
        val instanceA = DemoClass(5)
        println(instanceA is DemoClass) // true
        println(instanceA is Any)       // true
    }
    

    相关文章

      网友评论

          本文标题:几种语言的==、===和is比较

          本文链接:https://www.haomeiwen.com/subject/kovfdrtx.html