# Dart operators

In this tutorial we cover Dart operators. With the operators, we show how to create expressions.

An operator is a symbol which indicates a certain process is executed. Operators in programming are taken from mathematics. The operators are used to process data. An operand is one of the inputs (arguments) of an operator.

Expressions are constructed from operands and operators. The operators of an expression indicate which operations to apply to the operands. The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators.

An operator usually has one or two operands. Unary operators work with only one operand. Those who work with two operands are called binary operators.

Some operators may be used in different contexts. For instance the `+` operator can be used in different cases: it adds numbers or concatenates strings. We say that the operator is overloaded.

## Dart minus sign operator

The minus sign operator `-` can be used to change the sign of a value.

minus_sign.dart
```void main() {
int a = 1;

print(-a);
print(-(-a));
}
```

The minus sign changes the sign of a value.

## Dart assignment operator

The assignment operator `=` assigns a value to a variable. A variable is a placeholder for a value. In mathematics, the = operator has a different meaning. In an equation, the `=` operator is an equality operator. The left side of the equation is equal to the right one.

```int x = 1;
```

Here we assign a number to the `x` variable.

```x = x + 1;
```

This expression does not make sense in mathematics, but it is legal in programming. The expression adds 1 to the `x` variable. The right side is equal to 2 and 2 is assigned to `x`.

```3 = x;
```

This code line leads to a syntax error. We cannot assign a value to a literal.

Dart contains the null-aware assignment operator `??=`, which assigns a value to a variable only if that variable is `null`.

```int x; // The initial value of x is null.
x ??= 6;
print(x); // 6
```

We assign value 6 to the `x` variable, because initially `x` is `null`.

```x ??= 3;
print(x); // 6
```

Since `x` is already non-null, the new value is not assigned to the variable.

### Dart increment and decrement operators

We often increment or decrement a value by one in programming. Dart has two convenient operators for this: `++` and `--`.

```x++; //  x = x + 1;
y--; // y = y - 1;
```
inc_dec.dart
```void main() {
var x = 6;

x++;
x++;

print(x);

x--;
print(x);
}
```

In the above example, we demonstrate the usage of both operators.

```var x = 6;

x++;
x++;
```

We initiate the `x` variable to 6. Then we increment `x` two times. Now the variable equals to 8.

```x--;
```

We use the decrement operator. Now the variable equals to 7.

```\$ dart inc_dec.dart
8
7
```

The increment and decrement operators are both prefix and suffix operators. Note that the usage of this operators may lead to unexpected results.

inc_dec2.dart
```void main() {
var r1 = increase(3);
print(r1);

var r2 = increase2(3);
print(r2);
}

int increase(int x) {
return ++x;
}

int increase2(int x) {
return x++;
}
```

In the `increase2` function, the value is returned before it is incremented.

```\$ dart inc_dec2.dart
4
3
```

## Dart compound assignment operators

The compound assignment operators consist of two operators. They are shorthand operators.

```a = a + 3;
a += 3;
```

The `+=` compound operator is one of these shorthand operators. The above two expressions are equal. Value 3 is added to the a variable.

Other compound operators include:

````-=   *=   /=   %=   &=   |=   <<=   >>=`
```
compound_operators.dart
```void main() {
var a = 1;
a = a + 1;

print(a);

a += 5;
print(a);

a *= 3;
print(a);
}
```

In the example, we use two compound operators.

```var a = 1;
a = a + 1;
```

The `a` variable is initiated to one. 1 is added to the variable using the non-shorthand notation.

```a += 5;
```

Using a `+=` compound operator, we add 5 to the `a` variable. The statement is equal to `a = a + 5`.

```a *= 3;
```

Using the `*=` operator, the `a` is multiplied by 3. The statement is equal to `a = a * 3`.

```\$ dart compound_assignment.dart
2
7
21
```

## Dart arithmetic operators

The following is a table of arithmetic operators in Dart.

SymbolName
`+`Addition
`-`Subtraction
`*`Multiplication
/Division
~/Integer division
`%`Remainder

arithmetic.dart
```void main() {
var a = 10;
var b = 11;
var c = 12;
var add = a + b + c;
var sb = c - a;
var mult = a * b;
var div = c / 3;
var rem = c % a;

print(sb);
print(mult);
print(div);
print(rem);
}
```

We use addition, subtraction, multiplication, division, and remainder operations. This is all familiar from the mathematics.

```var rem = c % a;
```

The `%` operator is called the remainder or the modulo operator. It finds the remainder of division of one number by another. For example, `9 % 4`, 9 modulo 4 is 1, because 4 goes into 9 twice with a remainder of 1.

```\$ dart arithmetic.dart
33
2
110
4
2
```

The following shows the distinction between integer and floating point division.

division.dart
```void main() {
var c = 5 / 2;
print(c);

var d = 5 ~/ 2;
print(d);
}
```

In the example, we divide two numbers.

```var c = 5 / 2;
print(c);
```

The `/` operator is a floating point division operator. The expression returns a floating point value.

```var d = 5 ~/ 2;
print(d);
```

The `~/` operator is an integer division operator. The expression returns an integer value.

```\$ dart division.dart
2.5
2
```

## Dart Boolean operators

In Dart we have three logical operators.

SymbolName
`&&`logical and
`||`logical or
`!`negation

Boolean operators are also called logical.

booleans.dart
```void main() {
var x = 3;
var y = 8;

print(x == y);
print(y > x);

if (y > x) {
print("y is greater than x");
}
}
```

Many expressions result in a boolean value. For instance, boolean values are used in conditional statements.

```print(x == y);
print(y > x);
```

Relational operators always result in a boolean value. These two lines print false and true.

```if (y > x) {
print("y is greater than x");
}
```

The body of the `if` statement is executed only if the condition inside the parentheses is met. The `y > x` returns true, so the message "y is greater than x" is printed to the terminal.

The `true` and `false` keywords represent boolean literals in Dart.

and_operator.dart
```void main() {
var a = true && true;
var b = true && false;
var c = false && true;
var d = false && false;

print(a);
print(b);
print(c);
print(d);
}
```

The code example shows the logical and (&&) operator. It evaluates to true only if both operands are true.

```\$ dart and_operator.dart
true
false
false
false
```

Only one expression results in true.

The logical or (`||`) operator evaluates to true if either of the operands is true.

or_operator.dart
```void main() {
var a = true || true;
var b = true || false;
var c = false || true;
var d = false || false;

print(a);
print(b);
print(c);
print(d);
}
```

If one of the sides of the operator is true, the outcome of the operation is true.

```\$ dart or_operator.dart
true
true
true
false
```

Three of four expressions result in true.

The negation operator `!` makes true false and false true.

negation.dart
```void main() {
print(!true);
print(!false);
print(!(4 < 3));
}
```

The example shows the negation operator in action.

```\$ dart negation.dart
false
true
true
```

## Dart comparison operators

Comparison operators are used to compare values. These operators always result in a boolean value.

SymbolMeaning
`<`less than
`<=`less than or equal to
`>`greater than
`>=`greater than or equal to
`==`equal to
`!=`not equal to

Comparison operators are also called relational operators.

comparison.dart
```void main() {
print(3 < 4);
print(3 == 4);
print(4 >= 3);
print(4 != 3);
}
```

In the code example, we have four expressions. These expressions compare integer values. The result of each of the expressions is either true or false. In Dart we use the `==` to compare numbers. (Some languages like Ada, Visual Basic, or Pascal use `=` for comparing numbers.)

## Dart bitwise operators

Decimal numbers are natural to humans. Binary numbers are native to computers. Binary, octal, decimal, or hexadecimal symbols are only notations of the same number. Bitwise operators work with bits of a binary number.

SymbolMeaning
`&`bitwise and
`|`bitwise or
`^`bitwise xor
`~`bitwise not
`<<`left shift
`>>`right shift

The bitwise and operator performs bit-by-bit comparison between two numbers. The result for a bit position is 1 only if both corresponding bits in the operands are 1.

```      00110
&  00011
=  00010
```

The first number is a binary notation of 6, the second is 3, and the result is 2.

```print(6 & 3); // prints 2
print(3 & 6); // prints 2
```

The bitwise or operator performs bit-by-bit comparison between two numbers. The result for a bit position is 1 if either of the corresponding bits in the operands is 1.

```     00110
| 00011
= 00111
```

The result is `00110` or decimal 7.

```print(6 | 3); // prints 7
print(3 | 6); // prints 7
```

The bitwise exclusive or operator performs bit-by-bit comparison between two numbers. The result for a bit position is 1 if one or the other (but not both) of the corresponding bits in the operands is 1.

```      00110
^  00011
=  00101
```

The result is `00101` or decimal 5.

```print(6 ^ 3); // prints 5
print(3 ^ 6); // prints 5
```

## Dart ternary operator

The ternary operator `?:` is a convenient conditional operator.

```cond-exp ? exp1 : exp2
```

If cond-exp is true, exp1 is evaluated and the result is returned. If the cond-exp is false, exp2 is evaluated and its result is returned.

ternary.dart
```void main() {
var age = 18;

var isAdult = (age >= 18) ? true : false;

} else {
print("he is minor");
}
}
```

You are adult if you are older than a certain age. This is a situation for a ternary operator.

```var isAdult = (age >= 18) ? true : false;
```

First the expression on the right side of the assignment operator is evaluated. The first phase of the ternary operator is the condition expression evaluation. So if the age is greater or equal to 18, the value following the `?` character is returned. If not, the value following the `:` character is returned. The returned value is finally assigned to the `adult` variable.

The Dart spread operator `...` provides a quick way to insert multiple values into a collection.

```void main() {
var vals = [1, 2, 3];
var vals2 = [...vals, 4, 5, 6];

print(vals);
print(vals2);
}
```

The example presents the spread operator.

```var vals2 = [...vals, 4, 5, 6];
```

With the help of the `...` operator, we insert all values of the `vals` into the new `vals2` collection.

```\$ dart spread.dart
[1, 2, 3]
[1, 2, 3, 4, 5, 6]
```

## Dart is & is! operators

With the `is` and `is!` operators, we check the type of an object at runtime.

is_operator.dart
```class Base {}

class Derived extends Base {}

void main() {
var b = Base();
var d = Derived();

print(d is Base);
print(d is! Base);
print(b is Derived);
print(d is Object);
print(d is! Object);
}
```

In the example, we check the types of objects.

```\$ dart is_operator.dart
true
false
false
true
false
```

## Dart operator precedence

The operator precedence determines which operators are evaluated first. The precedence level is necessary to avoid ambiguity in expressions.

What is the outcome of the following expression, 33 or 48?

```3 + 5 * 6
```

Like in mathematics, the multiplication operator has a higher precedence than addition operator. So the outcome is 48.

```(3 + 5) * 6
```

To change the order of evaluation, we can use parentheses. Expressions inside parentheses are always evaluated first. The result of the above expression is 48.

precedence.dart
```void main() {
print(3 + 5 * 6);
print((3 + 5) * 6);

print(!true || true);
print(!(true || true));
}
```

The outcome of each expression in the example is dependent on the precedence level.

```print(3 + 5 * 6);
```

This line prints 33. The multiplication operator has a higher precedence than addition. First, the product of `5 * 6` is calculated, then 3 is added.

```print((3 + 5) * 6);
```

The evaluation of the expression can be altered by using round brackets. In this case, the `3 + 5` is evaluated and later the value is multiplied by 5. This line prints 48.

```print(!true || true);
```

In this case, the negation operator has a higher precedence than the bitwise or. First, the initial true value is negated to false, then the `|` operator combines false and true, which gives true in the end.

```\$ dart precedence.dart
33
48
true
false
```

## Associativity rule

Sometimes the precedence is not satisfactory to determine the outcome of an expression. There is another rule called associativity. The associativity of operators determines the order of evaluation of operators with the same precedence level.

```9 / 3 * 3
```

What is the outcome of this expression, 9 or 1? The multiplication, deletion, and the modulo operator are left to right associated. So the expression is evaluated this way: `(9 / 3) * 3` and the result is 9.

Arithmetic, boolean and relational operators are left to right associated. The ternary operator, increment, decrement, unary plus and minus, negation, bitwise not, type cast, object creation operators are right to left associated.

associativity.dart
```void main() {
var j = 0;

j *= 3 + 1;

print(j);
}
```

In the example, we the associativity rule determines the outcome of the expression.

```var j = 0;

j *= 3 + 1;
```

The compound assignment operators are right to left associated. We might expect the result to be 1. But the actual result is 0. Because of the associativity. The expression on the right is evaluated first and then the compound assignment operator is applied.

In this tutorial, we have covered Dart operators.

List all Dart tutorials.