Skip to main content
The + operator in Dart is a binary, left-associative additive operator used for arithmetic addition and object concatenation. Architecturally, Dart implements operators as instance methods. When the expression a + b is evaluated, the Dart compiler resolves it as an invocation of the + method defined on the left operand’s class, passing the right operand as the single argument.

Syntax and Resolution

operand1 + operand2;
Because the operation is resolved against the left operand’s class definition, the type of the right operand must satisfy the parameter type defined by the left operand’s operator + signature.

Type-Specific Behaviors

Numeric Types (int, double, num) When applied to numeric types, the operator performs standard arithmetic addition. Dart enforces type promotion rules during this operation:
  • int + int returns an int.
  • double + double returns a double.
  • int + double (or vice versa) promotes the int to a double and returns a double.
int a = 5;
double b = 2.5;
Type resultType = (a + b).runtimeType; // double
Strings (String) When invoked on a String, the operator performs concatenation, returning a new String allocated in memory. Dart is strictly typed regarding string concatenation; the right operand must also be a String. Implicit coercion of non-string types does not occur.
String s1 = "Hello";
String s2 = " World";
String s3 = s1 + s2; 

// String s4 = s1 + 5; // Compile-time error: The argument type 'int' can't be assigned to the parameter type 'String'.
Lists (List<E>) When applied to List objects, the + operator returns a new List<E> containing all elements from the left list followed by all elements from the right list. Both operands must be lists, and their generic types must be compatible.
List<int> list1 = [1, 2];
List<int> list2 = [3, 4];
List<int> combined = list1 + list2; // [1, 2, 3, 4]

Operator Overloading

Developers can define the + operator for custom classes using the operator keyword. The method must take exactly one parameter (the right operand) and should ideally return a new instance of an object rather than mutating the existing instance, adhering to expected value-type semantics.
class Vector {
  final int x;
  final int y;

  const Vector(this.x, this.y);

  // Overriding the + operator
  Vector operator +(Vector other) {
    return Vector(this.x + other.x, this.y + other.y);
  }
}

Vector v1 = Vector(1, 2);
Vector v2 = Vector(3, 4);
Vector v3 = v1 + v2; // Resolves to Vector(4, 6)

Precedence and Associativity

  • Associativity: Left-to-right. An expression like a + b + c is evaluated as (a + b) + c.
  • Precedence: The + operator sits at the “Additive” precedence level. It is evaluated after Multiplicative operators (*, /, ~/, %) and before Shift operators (<<, >>, >>>) and Relational operators (<, >, <=, >=).
Tired of Poor Dart Skills? Fix That With Deep Grasping!Learn More