Search code examples
dartidentityequality

Equality and identity in Dart


I am just starting to study Dart and a question arose, a clear answer to which I could not find or formulate for myself. I'm trying to figure out the difference between == and identity(). Using the example of this code snippet:

void main() {
  var a = [1, 2, 3];
  var b = a;
  var c = [1, 2, 3];

  print(identical(a, b)); // true
  print(identical(a, c)); // false
  print(a == c);  // false
}

I have a little experience in python and there this code gives me understandable results:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a == b
True
>>> a is b
False

And in Dart it is not clear for me. If identity and == on basic data types give the same results, then why are they different 😅 ? Is there a difference between them if I'm not familiar with the classes in Dart?

I will be grateful for any clarifications that will help me figure out the issue.


Solution

  • The example below might help to illustrate the usage of the operator == and the function identical.

    • By default, == and identical return the same result. See first example, where two objects of type A are compared. The hashCode can be thought of as an object id. Note: Classes may override the == operator and the getter hashCode. For this reason it makes sense to have the function identical which is the equivalent of Python's is.

    • The second example is slightly different since both variables s1 and s2 are assigned a literal, in this case a String literal. (To achieve a similar behaviour with class A, we could define a const constructor and use that constructor when assigning the values of a1 and a2.)

    • The third example is similar to the second one. In this case, l1 and l2 are both assigned the same constant list object.

    • The forth example shows that (non-constant) collections (lists, sets, maps, etc) are only equal == if they are also identical, even if their elements are the same.

    class A{}
    
    void main() {
      
      print('\nClass A');
      final a1 = A();
      final a2 = A();
      print(a1 == a2); // false
      print(identical(a1, a2)); // false
      print(a1.hashCode);
      print(a2.hashCode);
      
      print('\nString');
      final s1 = 'hi'; 
      final s2 = 'hi';
      print(s1 == s2); // true
      print(identical(s1, s2)); // true
      print(s1.hashCode);
      print(s2.hashCode);
      
      print('\nConst list');
      final l1 = const [0, 1, 2]; 
      final l2 = const [0, 1, 2]; 
      print(l1 == l2); // true
      print(identical(l1, l2)); // true
      print(l1.hashCode);
      print(l2.hashCode);
      
      print('\nList');
      final l3 = [0, 1, 2]; 
      final l4 = [0, 1, 2]; 
      print(l3 == l4); // false
      print(identical(l3, l4)); // false
      print(l3.hashCode);
      print(l4.hashCode);
    }
    

    The console output is shown below:

    Class A
    false
    false
    945090685
    653872300
    
    String
    true
    true
    793667904
    793667904
    
    Const list
    true
    true
    996765025
    996765025
    
    List
    false
    false
    61814395
    515290226