×

Dart Operators Precedence and Associativity

Precedence of operators determines the order in which the operators are evaluated if they are grouped together in a sentence. If two operators share an operand then the one with the higher precedence is executed first.

Program

Consider the following code in Dart that uses two Arithmetic Operators viz multiply (*) and add (+), and an assignment operator viz. equals to (=).

void main( )
{
    int a = 5, b = 6, c = 7, res1 = 0, res2 = 0 ;
  
    res1 = a + b * c ;
  
    // result of first expression
    print( res1 ) ;
  
    res2 = a * b + c ;
    
    // result of second expression
    print( res2 ) ;
}

Output:

47
37

Let us understand how the answers to these two results differ. In the first expression res1 = a + b * c with a = 5, b = 6, and c = 7.

Multiplication is performed first because it has higher precedence than the addition operator.

Therefore, the answer evaluated to 47.

res1 = a + b * c = 5 + 6 * 7

                                 = 5 + 42

                              = 47

Similarly in case of second expression,

Multiplication is performed first followed by addition

res2 = a * b + c = 5 * 6 + 7

                                = 30 + 7

                                = 37

Since the assignment operator has the least precedence out of these three, it is used at the last after we have evaluated the expression at the right. And then using assignment operator the value evaluated is assigned to the variable on the left.

Sometimes, the operators with same precedence are used in an expression together. In that case we need a rule that defines the order in which they should be performed and that is given by Associativity of the operators. It determines the direction in which an expression is evaluated. It can be either Left to Right or Right to Left.

Program

Consider the following code in Dart that uses Multiplicative operators  : multiply (*) and divide (/), Additive Operators : add (+) and subtract (-) and assignment operator : equals to (=)

void main( )
{
    int a = 12, b = 6, c = 16, d = 8;
    var res1, res2, res3, res4;
  
    res1 = a - b + c * d;
  
    // result of first expression
    print( res1 ) ;
  
    res2 = a / b * c + d ;
    
    // result of second expression
    print( res2 ) ;
  
    res3 = a * b / c - d ;
  
    // result of third expression
    print( res3 ) ;
  
    res4 = a + b - c / d ;
  
    // result of fourth expression
    print( res4 ) ;
}

Output:

134
40
-3.5
16

PRECEDENCE AND ASSOCIATIVITY TABLE

Let’s have a look at the table that defines the precedence and associativity of each operator in Dart.

LEVELCATEGORYOPERATORASSOCIATIVITY
16Unary Postfixexpr.
expr ?.
expr ++
expr --
expr1
[ expr2 ]
expr( )
 
15Unary Prefix- expr
! expr
++ expr
-- expr
~ expr
await expr
 
14Multiplicative*
/
~
/
%
Left – to - right
13Additive+
-
Left - to - right
12Shift< <
> >
> > > >
Left – to - right
11Bitwise AND&Left - to - right
10Bitwise XOR^Left – to - right
9Bitwise OR Postrix|Left – to - right
8Relation and Test type

< =
> =
as
is
is! 
 
7Equality= =
= !
 
6Logical AND&&Left – to - right
5Logical OR| |Left - to - right
4If nullexpr1 ?? expr2Left – to - right
3Conditionalexpr ? expr1 : expr2Right - to - left
2Cascade. .Left – to - right
1Assignment=
* =
/ =
+ =
- =
& =
^ =
< * lt ; =
>> =
?? =
~ / =.
| =
% =
Right - to - left

Overriding Precedence

We are clear by now that the operators are executed in an expression as per their precedence. But what if we want them to be executed exactly in the sequence they are written in an expression?

For example

In an expression that contains multiplication operator (*) and addition operator (+), we know that multiplication will be done first. But in order to perform addition first, we can use round parenthesis with the operator and operands.

Consider the following code in Dart that explains the above point

void main( )
{
    int a = 5, b = 6, c = 7;
    var res1, res2, res3, res4 ;
  
    res1 = a + b * c ;
    
    // printing the result of first expression
    print( res1 ) ;
  
    res2 = a * b + c ; 
  
    // printing the result of second expression
    print( res2 ) ;
  
    res3 = ( a + b ) * c ;
  
    // printing the result of third expression
    print( res3 ) ;
  
    res4 = ( a * b ) + c ;
  
    // printing the result of fourth expression
    print( res4 ) ;
} 

Output:

47
37
77
37

Precedence Class

A particular row in the Dart expression precedence table is represented by an instance of the expression class. This allows programmers to determine when parentheses are required (by comparing precedence values), but ensures that the programmer does not depend on the particular integers used by the analyser to represent table rows, since it may be required to change these integers from time to time to accommodate new language features.

Constructors

  1. Precedence.forTokenType constructor = This constructor is used to construct the precedence of the unary or binary expression containing operators of a particular given ‘type’.

Implementation = Precedence.forTokenType ( TokenType type ) : this._( type.precedence ) ;

Properties

1. HashCode =

Returns the hash code for a numerical value, and it returns the same value for int and doubles when the value provided is the same. 

Implementation =

@override

int get hashCode = > _index.hashCode ;

2. Runtime Type =

Represents the type of runtime an object has. 

Implementation = external Type get runtimeType ;

Operators

1. Operator <

It checks whether the precedence represents a looser binding than other, and accordingly returns true or false.

Implementation = bool operator < ( Precedence other ) = > _index < other._index ;

2. Operator < =

It checks whether the precedence represents a looser, or equal binding than other, and accordingly returns true or false.

Implementation = bool operator < = ( Precedence other ) = > _index < = other._index ;

3. Operator = =

It returns true if and only if this object and the other are the same.

Implementation =

@override

bool operator = = ( Object other ) = >

    other is Precedence && _index = = other._index ;

4. Operator >

It checks whether the precedence represents a tighter binding than other, and accordingly returns true or false.

Implementation = bool operator > ( Precedence other ) = > _index > other._index ;

5. Operator > =

It checks whether the precedence represents a tighter, or equal binding than other, and accordingly returns true or false.

Implementation = bool operator > = ( Precedence other ) = > _index > = other._index ;


Related Topics

Dart Booleans

Booleans Dart has a data type named ‘bool’ to represent Boolean values : true and false, which are compile-time constants. ‘True’ or ‘False’ cannot be assigned with values 1 or 0. Example, bool...

1 minute read.

Dart Generators

Synchronous Generator Dart Generator is a unique function that allows us to generate price sequences. Generators return values when needed; means that the value is generated if we try to duplicate...

5 minutes read.

Dart Tutorial

Dart is an open-source, structured programming language developed by Google. It is a high-level programming language that emerged in 2011, but its stable version emerged in 2017. It is largely used...

4 minutes read.

Common Collection Methods

Most of the programming languages have arrays as a way to list items together. However, Dart has a collection of data structures similar to array. These are supported by the...

3 minutes read.

Dart Exception Handling

Exception Class – An exception is any runtime error that leads to abrupt termination of the program. It helps in addressing the error programmatically. It is aimed to be caught...

4 minutes read.

Dart Static Members

Static Members in Dart Static members are the members of the class declared using the 'static' keyword. the static members have the following characteristics :  All the objects of the class having...

3 minutes read.

Dart Objects

Apart from the built-in data types, Dart offers some other data types that have a special role to play. One of them is Objects.  Objects Objects are the foundation of the...

3 minutes read.

Type System in Dart

Dart language is a type safety enabled language that uses static and dynamic type checking to match the value of the variable with its data type at the compile-time. This...

4 minutes read.

Dart Variables

Variables are used to store the value of a particular data type referred to in the whole program by a name or identifier. They refer to a memory location as...

5 minutes read.

Dart Packages

Every programming language has some in-built functions stored inside the header files that makes the task much easier for the programmer. The Dart Packages refer to the compilation of a...

4 minutes read.

C++ vs Dart

Difference between C++ and Dart C++ is an object-oriented programming language developed in 1980 by Bjarne Stroustrup. It has wide real-world applications with various in-built functions and a very vast library...

1 minute read.

Dart Iterable

Iterable is a collection of elements that are accessed sequentially. These elements are accessible using the iterator getter and stepping through the values using this getter. Let us understand the setting...

6 minutes read.

Dart Equality and Relational Operators

Dart provides the functionality of checking the relationship between the values or values within the variables. These operators return the resultant value as Boolean, i.e., either ‘true’ or ‘false’. Some important points...

3 minutes read.

Dart Logical Operators

Logical operators are the operators that combine two or more conditions, and accordingly return a Boolean value : true or false. Assume the value of variable A is 25 and B...

2 minutes read.

Dart Construtors

Constructors are the very important concept in any programming language. They are the special functions created in the classes to allocate memory to the objects of that class when created...

4 minutes read.

Dart Constants

Dart Constants are the objects or variables whose values can’t change or modify during the execution of the program. Their use case is when we want a particular value to...

2 minutes read.

Dart Types of Functions

Functions are the set of statements intended to perform a specific task. They accept some input from the user, perform the specified computation and generate the output. They are very...

4 minutes read.

Dart this Keyword

The ' this ' keyword, similar to that in Java and C#, refers to an object of the class using it. It points to the current object of the class,...

5 minutes read.

Abstract Classes in Dart

Abstract classes in Dart are those classes that only contain abstract methods  (methods that do not contain any implementation). These classes are specifically designed for the purpose of inheritance. We...

4 minutes read.

Dart - Control Flow Statements

The control flow statements are used to define the control on the flow of the program. Dart programs are executed in sequential order i.e., the order in which the programming...

1 minute read.