【问题标题】:How does a set determine that two objects are equal in dart?一个集合如何确定两个对象在飞镖中相等?
【发布时间】:2015-06-16 12:29:10
【问题描述】:

我不明白集合如何确定两个对象何时相等。更具体地说,集合的add方法什么时候真正添加了一个新对象,什么时候不作为一个新对象,因为该对象已经在集合中?

例如,我有以下类的对象:

class Action {
  final Function function;
  final String description;

  Action(this.function, this.description);

  call() => function();

  toString() => description;
}

现在我认为以下集合将包含 2 个元素,因为其中 2 个是相等的:

void main() {
  Set<Action> actions = new Set()
    ..add(new Action(() => print("a"), "print a"))  
    ..add(new Action(() => print("a"), "print a"))
    ..add(new Action(() => print("b"), "print b"));
}

但是,这个集合包含 3 个Action 对象。请参阅demo。如何确保在集合中相等的对象被视为相等?

【问题讨论】:

    标签: dart


    【解决方案1】:

    有关 Dart 中的 operator== 的全面报道,请参阅 http://work.j832.com/2014/05/equality-and-dart.html

    它只是检查它们是否相等 a == b 您可以覆盖 == 运算符来自定义此行为。请记住,当== 运算符被覆盖时,hashCode 也应该被覆盖。

    class Action {
      @override
      bool operator==(other) {
        // Dart ensures that operator== isn't called with null
        // if(other == null) {
        //   return false;
        // }
        if(other is! Action) {
          return false;
        }
        return description == (other as Action).description;
      }
    
      // hashCode must never change otherwise the value can't
      // be found anymore for example when used as key 
      // in hashMaps therefore we cache it after first creation.
      // If you want to combine more values in hashCode creation
      // see http://stackoverflow.com/a/26648915/217408
      // This is just one attempt, depending on your requirements
      // different handling might be more appropriate.
      // As far as I am aware there is no correct answer for
      // objects where the members taking part of hashCode and
      // equality calculation are mutable.
      // See also http://stackoverflow.com/a/27609/217408
      int _hashCode;
      @override
      int get hashCode {
        if(_hashCode == null) {
          _hashCode = description.hashCode
        }
        return _hashCode;
      }
      // when the key (description) is immutable and the only
      // member of the key you can just use
      // int get hashCode => description.hashCode
    }
    

    试试DartPad

    【讨论】:

    • operator== 的参数永远不会是 null,因为在调用 operator== 之前会明确检查 null。您可以删除other == null 检查。
    • 太好了,非常感谢!这不是我记得的,但它更全面。
    【解决方案2】:

    这是一个测试顶级函数、静态方法和实例方法是否相等的示例:

    void foo() {} // A top-level function
    
    class A {
      static void bar() {} // A static method
      void baz() {} // An instance method
    }
    
    void main() {
      var x;
    
      // Comparing top-level functions.
      x = foo;
      assert(foo == x);
    
      // Comparing static methods.
      x = A.bar;
      assert(A.bar == x);
    
      // Comparing instance methods.
      var v = A(); // Instance #1 of A
      var w = A(); // Instance #2 of A
      var y = w;
      x = w.baz;
    
      // These closures refer to the same instance (#2),
      // so they're equal.
      assert(y.baz == x);
    
      // These closures refer to different instances,
      // so they're unequal.
      assert(v.baz != w.baz);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-17
      • 2022-12-04
      • 1970-01-01
      相关资源
      最近更新 更多