在Dart中,“is”和“==”有什么区别?

6

假设我有:

class Test<T> {
  void method() {
    if (T is int) {
      // T is int
    } 

    if (T == int) {
      // T is int
    }
  }
}

我知道我可以重载==运算符,但是如果我没有重载任何运算符,在Dart中==is之间的主要区别是什么。


编辑:

假设我有以下代码:

extension MyIterable<T extends num> on Iterable<T> {
  T sum() {
    T total = T is int ? 0 : 0.0; // setting `T == int` works
    for (T item in this) {
      total += item;
    }
    return total;
  }
}

当我使用我的扩展方法时,比如:

var addition = MyIterable([1, 2, 3]).sum();

我遇到了这个错误:

类型“double”不是类型“int”的子类型

2个回答

7
  • identical(x, y)检查x是否是与y相同的对象。

  • x == y检查x是否应被视为等于y operator ==的默认实现identical()相同,但可以重写operator ==以执行深度相等性检查(或在理论上可以病态地实现任何操作)。

  • x is T检查x是否具有类型Tx是一个对象实例

class MyClass {
  MyClass(this.x);

  int x;

  @override
  bool operator==(dynamic other) {
    return runtimeType == other.runtimeType && x == other.x;
  }

  @override
  int get hashCode => x.hashCode;
}

void main() {
  var c1 = MyClass(42);
  var c2 = MyClass(42);
  var sameC = c1;

  print(identical(c1, c2));    // Prints: false
  print(identical(c1, sameC)); // Prints: true

  print(c1 == c2);    // Prints: true
  print(c1 == sameC); // Prints: true

  print(c1 is MyClass);      // Prints: true
  print(c1 is c1);           // Illegal.  The right-hand-side must be a type.
  print(MyClass is MyClass); // Prints: false
}

请注意最后一个案例:MyClass is MyClassfalse,因为左侧是一个类型,而不是MyClass实例。(但是MyClass is Type则为true。)
在您的代码中,T is int是不正确的,因为两边都是类型。您需要在这种情况下使用T == int。请注意,T == int将检查精确类型,并且如果一个是另一个的派生类型,则不会为真(例如,int == num将为false)。

1
这可能是最好的答案,非常感谢您,我希望我能投更多的赞。 - iDecode

4

基本上,== 是等号操作符,而 "is" 是 Dart 的 instanceof 操作符(如果您来自 Java 背景,则告诉您某物是否为某种类型,否则也是如此)。

使用 == 进行相等性比较,当您想要检查两个对象是否相等时。 您可以在您的类中实现 == 运算符(方法)来定义基于什么判断两个对象是否相等。

以此例为例:

class Car {
    String model;
    String brand;
    Car(this.model, this.brand);

    bool operator == (otherObj) {
        return (otherObj is Car && other.brand == brand); //or however you want to check
        //On the above line, we use "is" to check if otherObj is of type Car
    }
}

现在,您可以根据您定义的条件来检查两辆汽车是否“相同”。
void main() {
  final Car micra = Car("Micra", "Nissan");
  print(micra == Car("Micra", "Nissan")); // true
  print(micra is Car("Micra", "Nissan")); // true
}

因此,"=="是你用来判断两个对象是否相等的东西,你可以覆盖它并根据你对两个对象如何被视为相等的期望进行设置。
另一方面,“is”基本上告诉你一个实例是否属于对象类型(这里micra属于Car类型)。

2
Dart 语言之旅包括关于相等运算符类型测试运算符的章节。 - jamesdlin
@jamesdlin 谢谢,这是否意味着如果两个对象相等,它们将始终是相同的? - iDecode
1
@iKeepChangingName 不是“identical”(完全相同的对象实例)意味着两个独立的对象可以是“==”(具有相同的内部值),但不会是“identical”。 - jamesdlin
@ Yudhishthir Singh 感谢您的回答,我已经知道了相同和相等的东西,我已经编辑了我的代码,您可以看到如果我使用 == 代码就能正常工作,但是使用 is 就会失败,我原本期望的是相反的结果。您能否解释一下为什么会出现这个错误? - iDecode
@jamesdlin非常感谢您,您非常有帮助,我已经更新了我的代码,请问您能否告诉我它的问题在哪里,如果您能发布一个答案,我将不胜感激。再次感谢 :) - iDecode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接