Let's start with an example. Observe the syntax and then read the notes below to understand what you see. This is how we do it in this tutorial. We give some examples then we explain the syntax.
Next example is a demo program. It has several variables and a method.
/* simple dart program */
void main() {
print('Hello, World!'); //output
}
A Dart program like any other computer program consist of code, libraries and data files. For now let's focus our attention of code. What are the elements we must understand to be able to read and write Dart code.
Let's start with documenting your code. When you write new code, you should add descriptions and ideas about your thinking and what your code will do. You can write this documentation inside your code by using "block comments". This is a short text surrounded by symbols /* ... */. It can span several lines of text.
Another more simple style to write comments is called "single line" comments. This kind of comments start with double slash symbol: // (like in C). You can add line comments at end of statement but not in the middle of a statement.
Finally, "expression comments" are comments that you can write inside of an expression or in the middle of a statement. Unfortunately Dart is using same notation for this kind of comments as block comments: /*...*/. This we know can make code unreadable.
Dart is a strongly typed language. Unlike Java in Dart you do not have to specify type all the time. The compiler is smart enough to assign a default type for your variables. This technology is called "type inference" and is common in modern languages.
/* example of variables */
var name = 'Voyager I'; //string variable
var year = 1977; //integer variable
var antennaDiameter = 3.7; //float variable
/* list collection */
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
/* composite variable (JSON) */
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg'
};
/* uninitialized numbers are null */
int LineCount;
assert(lineCount == null);
Note:In Dart, all things are Objects. Even the primitive types are objects. Every object is an instance of a class. Even functions, and null values are objects. All objects inherit from the Object class.
1. You declare a variable using keyword: "var" follow by an "identifier". That is a name we give to a variable. The name is case sensitive and usually starts with lowercase character and can contain numbers, uppercase characters and underscore
2. Unlike Java in Dart we do not use "accessor modifiers". In Dart all variables are private into a library or scope, except variables that start with underscore. These variables are public.
3. Uninitialized variables have an initial value of null. Even variables with numeric types are initially null, because numbers, like everything else in Dart are objects.
This concept should be familiar to you from mathematics. We form an expression in Dart using identifiers, functions, operators and punctuation symbols like round parenthesis, "()" and comma ",". Simplest expressions are constant literals.
Expressions return a value that can be captured into a variable or it can be used immediately to create larger expressions. Expression value is computed by algorithms associated to each operator. We can use round parenthesis in larger expressions to alter the order of evaluation for each smaller expressions.
/* simple expressions */
1 //a constant literal
3/2; //a division
3*2; //a multiplication
/* two complex expressions */
(a + b + c)/3
sqrt(pow(width,2) + pow(height,2))
Statements are specific to programming but one particular statement is most common and also known in mathematics. This is called assignment and is done in Dart using symbol equal "=". Other statements in Dart consist of a logical enumeration of keywords, expressions and punctuation symbols.
One statement can be usually a single line of code terminated with semicolon ";". Other times we can have more then one statement in a single line of code. Each statement is separated by semicolon ";" from the next one.
There are statements that can span several lines of code. Some statements have one or more blocks of code that have inside other statements. This is how we define a "scope" for a statement.
A block of code is a group of statements enclosed in squiggly brackets: { ... }. We use blocks of code to define a section of code. When we declare a variable in a section, the variable become local and is visible only in current scope. This is good to encapsulate the logic and avoid loosing track of purpose for a specific variable or identifier.
Dart use English short words and abbreviations that are part of Dart syntax and can not be used for any other purpose in a program, except in comments. These are also called "reserved words" and you must avoid using these words as identifiers when you create code. Dart has 61 keywords:
Category | Keyword | Description |
---|---|---|
Variables and Data Types | var | Declares a variable with inferred type. |
int | Declares an integer variable. | |
bool | Declares a boolean variable. | |
Functions | void | Indicates that a function returns no value. |
return | Exits a function and returns a value. | |
async/await | Specifies that a function can be suspended until an asynchronous operation is done, allowing other code to run in the meantime. | |
Control Flow | if | Executes a statement if a condition is true. |
else | Executes a statement if the if condition is false. | |
procedural | Enables conditional or iterative execution of code fragments | |
for | Executes a statement repeatedly a certain number of times. | |
while | Executes a statement repeatedly while a condition is true. | |
do-while | Executes a statement repeatedly while a condition is true, until the condition becomes false. | |
return | Exits the current function and returns a value. | |
Classes and Objects | class | Declares a class. |
new | Instantiates a new object from a class. | |
factory | Specifies that a class constructor can return an object other than the newly allocated instance. | |
mixin | Integrates other class features without using inheritance to inherit from them. | |
Asynchronous programming | async | Declares a function that can run asynchronously. |
await | Pauses the execution of an asynchronous function until a Future is completed, then resumes execution with the value returned by the Future. | |
Other Keywords | const | Declares a compile-time constant. |
static | Specifies that a variable or function belongs to a class and not to an instance of the class. | |
typedef | Defines a function signature for use as a type. | |
Library organization | part | Indicates a part of a library to be combined with other library parts into a single library. |
typedef | Declares a function signature that can be used as a type. |
Dart supports operators similar to all C based languages. The operators are polymorphic that means operators can operate on multiple data types. Each operator is in fact a method that supports two parameters (operands) and produce one result. Some operators need only one operand.
We have listed operators to be learned in logical order. So that you understand better we start with most simple operators and continue down with more complex.
Operator type | Description |
---|---|
Arithmetic Operators | Can operate on numbers, return numbers |
Bitwise Operators | Can operate on integer numbers, return integer. |
Logical Operators | Can operate on Booleans, return Boolean |
Comparison Operators | Can operate on numbers, return Boolean |
Assignment Operators | Can operate on a variable and expression of same type |
These operators are used to create numeric expressions.
Operator | Name | Description | Example |
---|---|---|---|
+ | Addition | Adds together two values | x + y |
- | Subtraction | Subtracts one value from another | x - y |
* | Multiplication | Multiplies two values | x * y |
/ | Division | Divides one value by another | x / y |
~/ | Division | Integer division | x ~/ 2 |
% | Modulus | Returns the division remainder | x % y |
++ | Increment | Equivalent to x = x + 1 | ++x or x++ |
-- | Decrement | Equivalent to x = x - 1 | --x or x-- |
Given two binary numbers A = 0011 and B=1010 here are the operators and results:
Operator | Meaning | Example | Result |
---|---|---|---|
& | bit and | A & B | 0010 |
| | bit or | A | B | 1011 |
^ | bit xor | A ^ B | 1001 |
~ | bit not | ~A | 1100 |
<< | shift left | 2 << A | 1100 |
>> | shift right | B >> 2 | 0010 |
These operators are also known as Boolean operators. They accept arguments of type Boolean and return Boolean results: true or false. Notice in Dart true is greater then false. Let's consider a == true and b == true in next examples:
Operator | Name | Description | Expression | Result |
---|---|---|---|---|
&& | and | Returns true if both statements are true | a && b | true |
|| | or | Returns true if one of the statements is true | a || b | true |
! | not | Reverse the result, returns false if the result is true | !a | false |
? | if | Ternary operator | a ? 0 : 1 | 0 |
These operators are used to in logical expressions but they compare any kind of things. In fact they are polymorphic operators. Can compare number primarily but also boolean or string operands. Important fact to know is that always return true/false Boolean values.
Operator | Name | Example |
---|---|---|
== | Equal to | x == y |
!= | Not equal | x != y |
> | Greater than | x > y |
< | Less than | x < y |
>= | Greater than or equal to | x >= y |
<= | Less than or equal to | x <= y |
These operators are also called "in-place" operators or "variable modifiers". Have double role: make an arithmetic operation and assign the result to left operand. The right operand can be a constant, variable or expression that return same type as the left operand.
Operator | Name | Expression | Equivalent |
---|---|---|---|
= | Assignment | x = 1 | x = 1 |
+= | Addition | x += 1 | x = x + 1 |
-= | Subtraction | x -= 1 | x = x - 1 |
*= | Multiplication | x *= 1 | x = x * 1 |
/= | Division | x /= 1 | x = x / 1 |
%= | Modulo | x %= 1 | x = x % 1 |
&= | Bitwise and | x &= 1 | x = x & 1 |
|= | Bitwise or | x |= 1 | x = x | 1 |
^= | Bitwise not | x ^= 1 | x = x ^ 1 |
>>= | left shift | x >>= 1 | x = x >> 1 |
<<= | right shift | x <<= 1 | x = x << 1 |
These operators are may produce different kind of data types depending on the expressions or statements they are used with. We have similar operators in other languages.
Operator | Name | Description |
---|---|---|
() | call | Call a function or method |
[] | index access | Access members into a list |
. | member access | Identify a member or field |
?. | cond. access | Used for nullable members |
?? | if null | Conditional expressions |
.. | cascade | Sequences of operations |
Next operators are based on keywords.
Operator | Meaning |
---|---|
as | Typecast (also used to specify library prefixes) |
is | True if the object has the specified type |
is! | False if the object has the specified type |
in | Check if element belong to a collection |
!in | Check if element does not belong to a collection |
While Dart syntax may have some minor complexity, it is relatively easy to learn for developers with experience in C like programming languages. It is a modern language with a concise and consistent syntax, that makes it ideal for rapid application development.
Dart has a similar syntax to C++, Go, Kotlin, Java. Does not require a significant amount of time for developers to become familiar with it. It applies a concise, straightforward, and logical syntax approach that is easy to understand.
Compared to Python, which is also considered to have a simple syntax, Dart's syntax can be a little bit more challenging due to its stricter syntax rules for declaring variables and type checking.
Read next: Data Types