reading notes on
Dart Up and Running
- Chapter 1, Quick Start
- Chapter 2, A Tour of the Dart Language
- Chapter 3, A Tour of the Dart Libraries
- Chapter 4, Tools
- Chapter 5, Walkthrough: Dart Chat
Chapter 1, Quick Start
(no notes)
Chapter 2, A Tour of the Dart Language
Important Concepts
- Everything you can place in a variable is an object, and every object is an instance of a class. All objects inherit from the
Object
class. - Static types, but it's optional. (objects with no specified type get a special type:
dynamic
) - Dart parses all you code before running it. (you can provide tips to Dart)
- Dart supports top-level functions (such as
main()
) - Dart supports top-level variables.
- Dart doesn't have the keyword
public, protected, and private
. if an identifier starts with an underscore_
, it's private to its library. - Identifiers can start with a letter or
_
, following by any combination of those characters plus digits. - Sometimes it matters whether something is an expression or an statement.
- Dart tools can report two kinds of errors: warnings and errors.
- Dart has two runtime modes: production and checked. (production mode is the default)
Variables
Variables are references.
Uninitialized variables have an initial value of null
.
int lineCount;
assert(lineCount == null);
the assert()
call is ignored in production mode.
you have the option of adding static types to your variable declarations:
String name = 'Bob';
for local variables, use var
, more details check Dart Style Guide
if you never intend to change a variable, use final
or const
, either instead of var
or in addition to a type:
final name = 'Bob';
// or
final String name = 'Bob';
a local, top-level, or class variable that's declared as final
is initialized the first time it's used. lazy initialization of final variables helps apps start up faster.
Built-in Types
Dart has special support for the following types:
- numbers
- strings
- booleans
- lists (also known as arrays)
- maps
you can initialize an object of any of above using a literal (you can also use constructors to do it)
Numbers
Dart numbers come in two flavors:
- int
- double (64-bit)
Both of them are subtypes of num
.
if number inclues a decimal, it's a double.
var x = 1; // int
var y = 1.1; // double
var one = int.parse('1'); // String -> int
var onePointOne = double.parse('1.1'); // String -> double
String oneAsString = 1.toString(); // int -> String
String piAsString = 3.14159.toStringAsFixed(2); // '3.14', double -> String
Strings
A Dart string is a sequence of UTF-16 code units. you can use either single or double quotes.
You can put the value of an expression inside a string by using ${expression}
. if the expression is an identifier, you can skip the {}
.
use ==
tests whether two objects are equivalent. two strings are equivalent if they have the same characters.
you can concatenate string using adjacent string literials:
var s = 'String ''concatenation'
" works even over line breaks.";
Another way to create a multi-line string: use a triple quote with either single or double quotation marks:
var s1 = '''
You can create
multi-line stirngs like this one
''';
you can create a raw string by prefix it with r
:
var s = r"In a raw string, even \n isn't special.";
Booleans
Dart has a type named bool
. only two objects have type bool: the boolean literals, true
and false
.
when Dart expects a boolean value, only the value true
is treaded as true. all other values are treated as false.
var name = 'Bob';
if (name) {
print('You have a name'); // Prints in JavaScript, not in Dart
}
run dart in checked mode to throw these kind of exceptions.
you should explicitly check for values:
// check empty string
assert(foo.isEmpty());
// check for zero
assert(foo <= 0);
// check for null
assert(foo == null);
// check for NaN
assert(foo.isNan());
Lists
Dart list literals look like JavaScript array literials:
var list = [1,2,3];
List type is a sub-type of Collection
Maps
a map is an object that associates keys and values.
var gifts = {
'first': 'partridge',
'second': 'turtledoves'
};
in map literials, each key must be a string. if you use a Map constructor, any object can be a key.
a map value can be any object, including null
.
if you look for a key that isn't in a map, you get a null in return:
assert(gifts['fifth'] == null);
Functions
exmaple of a function:
void printNumber(num number) {
print('The number is $number.');
}
// omitting types is ok
printNumber(number) {
print('The number is $number.');
}
in function that contains just one expression, you can use a shorthand syntax:
printNumber(number) => print('The number is $number.');
the => expr;
syntax is a shorthand for { return expr;}
.
only an expression - not a statement - can appear between =>
and ;
a function can have two types of parameters: required or optional. required parameters are listed first, followed by any optional parameters.
optional parameters can be either positional or named, but not both.
both kinds can have default values. the default value must be compile-time constants such as literals.
if you need to know whether the caller passed in a value for an optional parameter, use the syntax ?param
:
if (?device) {
// ...
}
optional named parameters
when calling a function, you can specify named parameters using paramName: value
:
enableFlags(bold: true, hidden: false);
when defining a function, use {param1, param2, ...}
to specify named parameters:
enableFlags({bool bold, bool hidden}) {
// ...
}
// use : to specify default values
enableFlags({bool bold: false, bool hidden: false}) {
// ...
}
optional positional parameters
wrapping a set of function parameters in []
marks them as optional positional parameters:
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
// use = to specify default values
String say(String from, String msg, [String device='carrier pigeon', String mood]) {
...
}
Functions as first-class objects
you can pass a function as a paramter to another function:
printElement(element) {
print(element);
}
var list = [1,2,3];
list.forEach(printElement);
you can assign a function to a variable:
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
Lexical closures
functions can close over variables defined in surrounding scopes.
Return Values
All functions return a value. (null
if not specified)
Equality and Relational Operators
how ==
operator works:
- if x or y is null, return
true
if both arenull
, andfalse
if only one isnull
- return the result of the method invocation
x.==(y)
Type Test Operators
if (person is Person) { // type check
person.firstName = 'Bob';
}
// shorter version
(person as Person).firstName = 'Bob';
use the as
operator to case an object to a particular type.
Control Flow Statements
if
,else if
, andelse
for
loopswhile
anddo-while
loopsbreak
andcontinue
switch
andcase
assert
Closures inside of Dart's for
loops capture the value of the index, avoiding a common pitfall found in JavaScript:
var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());
// 0 then 1 in dart
// 2 then 2 in javascript
If the object is a Collection, you can use forEach
using forEach
is a good option if you don't need to know the current iteration counter.
candidates.forEach((candidate) => candidate.view());
Collections also support the for-in form of iteration:
var collection = [0, 1 2];
for (var x in collection) {
print(x);
}
Break and Continue
use break
to stop looping
while(true) {
if (shutDownRequested()) break;
processIncomingRequests();
}
use continue
to skip to the next loop iteration:
for (int i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
if (candidate.yearsExperience < 5) {
continue;
}
candidate.interview();
}
// shorter version if using Collection
candidates.filter((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
Switch and Case
switch
in dart using ==
for comparison.
each non-empty case
clause ends with a break
statement, other valid ways to end it are countinue
, throw
, or return
use continue
and label:
switch(command) {
case 'CLOSED':
executeClosed();
continue nowClosed; // to nowClosed label
nowClosed:
case 'NOW_CLOSED':
// runs for both CLOSED and NOW_CLOSED
executeNowClosed();
break;
}
A case
clause can have local variables, which are visible only inside the scope of that clause.
Assert
Assert statements work only in checked mode, have no effect in production mode.
when assertion fails, AssertionError
exception is thrown.
Exceptions
if the exception isn't caught, the isolate that raised the exception is suspended, and typically the isolate and its program are termincated.
all of dart's exceptions are unchecked exceptions.
dart provides Exception and Error types. however, cart program can throw any non-null object - not just Exception and Error objects - as an exception.
Throw
throw new ExpectException("...");
// or throw arbirary objects.
throw '...';
throwing an exception is an expression, you can throw exceptions in =>
statements:
String get prettyVersion() => throw const NotImplementedException();
Catch and Finally
try {
breedMoreLlamas();
} on OutOfLlamasException { // a specific exception
buyMoreLlamas();
} on Exception catch(e) { // anything else that is an exception
print('Unknown exception: $e');
} catch(e) { // no specified type, handles all
print('Something really unknown: $e');
} finally {
cleanLlamaStalls();
}
you can use either on
or catch
or both.
use on
when you need to specify the exception type. use catch
when your exception handler needs the exception object.
Classes
Chapter 3, A Tour of the Dart Libraries
dart:core - Numbers, Collections, Strings, and More dart:async - Asynchronous Programming dart:math - Math and Random dart:html - Browser-Based Apps dart:io - I/O for Command-Line Apps dart:convert - Decoding and Encoding JSON, UTF-8, and More dart:mirrors - Reflection
Chapter 4, Tools
pub: The Dart Package Manager Dart Editor Dartium: Chromium with the Dart VM dart2js: The Dart-to-JavaScript Compiler dart: The Standalone VM dartanalyzer: The Static Analyzer
Chapter 5, Walkthrough: Dart Chat
How to Run Dartiverse Search How Dartiverse Search Works The Client's HTML Code The Client's Dart Code The Server's Code What Next?