美文网首页
几种语言的==、===和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