Dart: Basic Cheatsheet
Dart is a programming language for building apps on multiple platforms, including Android, iOS, the web and desktops. A descendent of ALGOL (just like C, Java, Javascript and C#), it is object-oriented, class-based, has a generational garbage collector and implements Actor model concurrency. Dart code can be ahead-of-time compiled directly to native ARM machine code, meaning it has very fast performance for mobile apps.
This cheatsheet is aimed at getting you started with Dart and will be expanded where necessary in future.
Give it a go
If you want to play around with Dart and follow the examples in this article, I highly recommend DartPad or Repl.it. These online tools give you an IDE to execute code for testing ideas, writing samples and more.
Code style
It's very important to maintain a consistent code style, especially when working on or with other people's Dart code.
Identifiers
- Use
UpperCamelCase
for naming types, such asCommandHandler
,LoginScreen
. - Use
lowerCamelCase
for class members, variables, parameters and constants - Use
lowercase_with_underscores
for packages, directories and source files.
Capitalisation
Using effective capitalisation gives your code improved readability. Acronyms and abbreviations should be capitalised like regular words, except for two-letter acronyms like DB:
HttpsFtpConnection
Id
DB
Variables
🚧 Warning
All uninitialised variables have a value ofnull
. The Dart team are working on a feature to allow marking variables non-nullable. Until that update appears, always keep in mind that it's safer to check fornull
.
Variables in Dart are defined as in other C-like languages:
String name = 'Murray Bauman';
You can also define final
variables that cannot be reassigned.
final Double pi = 3.14159;
pi = 991.1322 // No way, Jose!
💡 Note
You can also define variables withvar
. This indicates to Dart that you don't care about the variable's type. This can cause unexpected issues and should be avoided in favour of actual types.
Variables prefixed with const
work just like final
, except the value provided must be a compile-time constant:
const Double kDefaultPaddingWidth = 20.0;
const Double kAccentColor = getColor(); // No way, Jose!
Immutability
You should be declaring most of your variables with final
or const
, since it's good practice for variables to be immutable. If something has a valid reason to change, then declare it with a mutable keyword like its type or var
.
When working with Flutter, declaring widgets as const
in your widget trees increases UI performance. This is because const
objects are canonicalised (each constant will only be created once).
Numbers
There are two types of numbers in Dart: int
and double
, both can hold 64-bit values:
int mass = 200;
double earthsCircumference = 40.075;
If an integer is used as the value for a double
, Dart automatically converts it to a real number:
double maxCacheTime = 300;
print(maxCacheTime); // 300
Strings
A string literal in Dart is usually written with single quotes '
, unless the literal contains apostrophes, in which case the string must be written with double-quotes "
or use an escape sequence \'
:
String name = 'Jim';
String quote = 'Well Flo, Flo... we\'ve discussed this. Mornings are for coffee and contemplation, Flo!';
String quote = "Well Flo, Flo... we've discussed this. Mornings are for coffee and contemplation, Flo!";
Multi-line strings
You can create a multi-line string by wrapping it in triple quotes """
:
String heroes = """I, I can remember
Standing, standing by the wall
And the guns, shot above our heads
And we kissed, as though nothing could fall
And the shame, the shame was on the other side,
Oh we can beat them, forever and ever
And we can be Heroes, just for one day""";
🚧 Warning
A multi-line string declared using"""
will preserve line breaks, meaning the text above will be output exactly as it is written.
To create a multi-line string that doesn't preserve line-breaks (say, if you want to wrap a long string in your editor), you can split up each portion into a regular string, terminated by a semicolon:
String chapterOne = 'Call me Ishmael.'
'Some years ago—never mind how long precisely—having little '
'or no money in my purse, and nothing particular to interest'
' me on shore, I thought I would sail about a little and see'
' the watery part of the world.';
Raw
Prefixing your string literal with r
creates a raw string in Dart. Raw strings allow you to treat backslashes \
as a literal character.
String name = r'First \n Second';
Booleans
A boolean holds a value that is truthy:
bool upsideDown = true;
Booleans don't always have to be assigned true
or false
, you can also use the result of an expression (so long as it returns a bool):
bool isCorrectInstance = widget is StatelessWidget;
bool shouldShowOptions = options.length > 0;
Operators
Dart supports operators found in most other languages, plus has a few of its own. Operators perform actions on and to operands. An operand is the thing that appears to the left or the right of an operator, i.e. 1 + 6
, i++
, 60 > 120
and so on:
Operands | Operator |
---|---|
1 , 6 |
+ |
i |
++ |
60 , 120 |
> |
Arithmetic
+ // add
- // subtract
* // multiply
/ // divide
% // modulo
++ // increment
-- // decrement
Equality
== // equal to
!= // not equal to
> // greater than
>= // greater than or equal to
< // less than
<= // less than or equal to
Assignment
= // assign the right operand value to the left
??= // assign the right operand value to the left if the left operand is null
Loops
A loop contains a block of specific instructions that are executed a pre-determined number of times. Here the loop will continue executing while i < 10
:
for (var i = 0; i < 10; i++) {
print(i+1);
}
You can also iterate over a collection using for in
, which will execute the block until there are no more items:
List<int> numbers = [1, 26, 63, 13, 455];
for (var number in numbers) {
print(number);
}
This will output:
1
26
63
13
455
Control flow
Control flow is the order of execution of your code statements within a function.
Conditionals
if (a <= b) {
// ...
}
If a function returns a boolean, you can use this in your if
statements too:
String topScorer = 'MADMAX';
if (topScorer.toLowerCase().contains('max')) {
// ...
}
In order to provide code for when the if
expression is false, you use an optional else if
or else
. else if
will be executed if the preceding if
expression fails and so on until an else
is encountered, or the block finishes.
if (isPortalOpen()) {
print('Portal is open');
} else if (isPortalOpen() && isElAvailable()) {
closePortal();
} else {
print('Portal is closed');
}
Switch
The switch statement is like a long group of if...else
statements but is much
easier to read:
String character = 'Alexei';
String quote;
switch (character) {
case 'Billy Hargrove': {
quote = "That's how you do it Hawkins, that's how you do it!";
}
break;
case 'Alexei': {
quote = 'Can we watch Looney Tunes now?';
}
break;
case 'Murray Bauman': {
quote = 'Who needs sunlight when we have one another, comrade? And a bottle of Stolichnaya!';
}
break;
case 'Bob Newby': {
quote = "What's at the 'X'? Pirate treasure?";
}
break;
}
print(quote);
Can we watch Looney Tunes now?
Functions
Functions in Dart are similar to most other languages. You declare a function with a return type, a name and parameters:
int square(int a) {
return a * a;
}
Like functional programming languages, functions in Dart are first-class objects which can be stored in a variable:
int Function(int, int) multiply = (int a, int b) {
return a * b;
};
multiply(4, 8);
The function above is called an anonymous function, lambda, or closure.
It can also be defined using the "fat arrow" =>
operator like this:
var multiply = (int a, int b) => a * b;
Optional arguments
You can mark a parameter as optional by wrapping it with braces. This allows it to be missed when calling the function and usually signifies something that isn't absolutely necessary.
String characterBio(String name, [int age]) {
print('Name: $name');
if (age != null) {
print('Age: $age');
} else {
print('We don\'t know how old they are');
}
}
characterBio(name: 'Joyce Wheeler', age: 39);
Named parameters
Named parameters are wrapped with curly braces, {}
. They allow you to pass arguments with additional context (the name of the parameter itself) and in any order. Because of this flexibility, named parameters are always optional.
String characterBio({String name, int age}) {
// ...
}
characterBio(name: 'Joyce Wheeler', age: 39);
Default values
Optional and named parameters can have a default value supplied to them. These are defined using =
equals and the value must be a compile-time constant.
String characterBio({String name, int age, String placeOfBirth = "Hawkins"}) {
// ...
}
characterBio(name: 'Joyce Wheeler', age: 39);
Assertions
An assertion is a kind of check provided by Dart which allows you to check a value is present and within an expected range. These assertions are only evaluated when in Production
(Dart) or Debug
(Flutter) modes.
int divide(int a, int b) {
assert(a != null);
assert(b != null);
return a / b;
}
multiply(null, 5) // AssertionError!
Collections
Collections are "buckets" that allow you to store multiple elements inside.
List
A list holds items that are indexed. These can either be growable or fixed-length using the List()
constructor:
List<String> growableCharacters = <String> [
'Dustin Henderson',
'Jonathan Byers',
'Jim Hopper',
'Nancy Wheeler',
'El',
'Demogorgon',
];
List<String> fixedCharacters = List(6);
fixedCharacters.add('Dustin Henderson');
fixedCharacters.add('Jonathan Byers');
fixedCharacters.add('Jim Hopper');
fixedCharacters.add('Nancy Wheeler');
fixedCharacters.add('El');
fixedCharacters.add('Demogorgon');
Map
A map holds a finite number of items as key/value pairs:
Map<String, String> userDetails = <String, String> {
'username': 'w.byers',
'password': 'theups1ded0wn',
'token': '0bb12b2ee6dd4107f2c203469a67bd18b089ecfcf90ed685775d0753d72c92d7'
};
Set
A set is like a list, however items inside it can only exist once. The default Set
implementation uses a LinkedHashSet
.
Set<String> locations = Set.of([
"Benny's Burgers",
'Hawkins National Laboratory',
'Starcourt Mall',
"Melvald's General Store"
]);
Because a value of "Benny's Burgers"
already exists in the locations
set, attempting to add another does nothing:
locations.add("Benny's Burgers");
print(locations);
{Benny's Burgers, Hawkins National Laboratory, Starcourt Mall, Melvald's General Store}
📜 See
For more on collections, check out Iterables
Enumerations
An enumeration is a group of constants that are handy for defining specific things that are unlikely to change. Each item in the enumeration has an index assigned to it, by default the first is 0
.
enum OrderStatus {
pending,
picked,
shipped,
complete
}
I think that just about covers all the basics of Dart.