dart by example
main
main() is the entrypoint for application
main() {
print('Hello, World');
}
Also, this works
main() => print('Hello')
values
main(){
print( "1+1=${1+1}" ) //prints "1+1=2"
}
for
main(){
for (var i = 0; i<3; i++) {
print( i )
}
var collection = [3,4,5]
for (var x in collection) { //<<-- This works like python
print(x)
}
}
conditionals
main(){
if (7%2 == 0) {
print('7 is even');
) else {
print('7 is odd')
}
//ternary operators
var isAlive = true;
var monday = isAlive?'doctor': null;
print(`$moday`) //prints "doctor"
}
null aware operators
main(){
var moday = 'doctor';
var tuesday;
var next = tuesday ?? monday; //Assign monday if tuesday is null
var wednesday;
next ??= wednesday; // Assign if not null
String thursday;
var length = thursday?.length; //Call function if not null
}
switch
main(){
var piece = 'knight';
switch(piece) {
case 'queen':
case 'bishop':
print('diagonal');
case 'knight':
print('L-shape')
}
}
class FoodSpoiledError extends StateError {
FoodSpoiledError (String msg) : super(msg);
}
class Potato {
int age;
Potato(this.age);
String peel() {
if (age>4) {
throw new FoodSpoiledError('Potato is spoiled')
}
return "peeled"
}
}
main(){
var p = Potato(7);
try {
p.peel();
} on FoodSpoiledError catch(_) {
print("no");
}
try {
throw("potato"); //Anything can be thrown as an error;
catch(_) {
print("caught potato");
}
// Exceptions without try catch halt execution
p.peel();
}
queue
main(){
var q = new Queue.from([300, 200, 100, 500]); //Optimised for adding items to the head or tail.
//Queues implement Iterable
print(q.takewhile(i) => i > 100)); //prints "{300, 200}"
//Consuming a queue
while (q.first > 100) {
q.removeFirst();
}
print(q); //print "{100,500}"
}
functions
yell(str) => str.toUpperCase(); //Valid function definition
List lines(String str) {
//^^ Return type
return str.split('\n');
}
main(){
var poemLines = lines(poem);
print(yell(poemLines.first)); //POEM
//Functions are first-class citizens
var whisper = (String str) => str.toLowerCase();
print(poemLines.map(whisper).last; //poem
}
poem = 'poem'
optional parameters
String yell(String str, [bool exclaim = false]) {
// ^^^^^^^^^^^ ordered optional parameter
var result = str.toLowerCase();
if (exclaim) result = result + '!!!';
return result
}
String whisper (String str, {bool mysteriously:false}) {
// ^^^^^^^ named optional parameter
var result = str.toLowerCase();
if (mysteriously) result = result + '....';
return result;
}
main() {
print (yell('Hello, World')); // prints "Hello, World"
print (yell('Hello, World', true)); // prints "Hello, World!!!"
print (whisper('Hello, World', mysteriously: true));
}
lexical scope
//variables declared inside loops will have a new version each time.
main(){
var functions = [];
for (var i=0; i<3; i++) {
functions.add(() => i);
}
functions.forEach((fn) => print(fn())); // prints 0\n1\n2\n
}
typedef
typedef bool Validator(int n); //Definition of a function to be used
main(){
Validator validate = (int n) => n>10
print('${both(5)}')
}
unused variables
- use underscore to silence dartanalyzer
constants
import `dart:math`;
const name = "greg"; //Compile time variable
const Rectangle bounds = const Rectangle (0,0,5,5); //Even objects can be declared compile time
final
Final is used when the value is not known at compile time. The values are immutable
main(){
final foo = "hello";
try {
foo = 'goodbye'; //Assignment not possible
} catch (e) {
print('error')
}
var pos = new Position(4);
try {
pos.x = 100 //Not possible as the variables are declared as final
} catch (e) {
print('error')
}
class Position {
final int x;
final int y;
Position(this.x) : y = 0;
}
static
Values are available in the class description itself instead of in an instance of a class
class Position {
static int get maxX => 100;
static int maxY = 200;
}
main(){
print(Position.maxX); //prints "100"
print(Position.maxY); //prints "200"
}
classes
import 'dart:math';
class Position {
// Properties, AKA class variables
int x;
int y;
//Simple constructor
Position(this.x, this.y);
// ^^^^^ note that, constructor has the same name as the class
//Additional constructors
// object can be created like, var x = new Position.atOrigin
Position.atorigin(){
x = 0;
y = 0;
}
//Factory constructors
factory Position.fromMap(Map m) => new Position(m['x'],m['y'])
//methods
double distanceTo(Position other) {
var dx = other.x - x;
var dy = other.y - y;
return sqrt(dx*dx + dy*dy)
}
}
main(){
var origin = new Position();
..x = 0
..y = 0; //<<-- updating properties
var p = new Position()
..x = -5
..y = 6;
print(origin.distanceTo(p)); //7.8
}
initializer lists + getters and setters
class Position {
final int x;
final int y;
final double rad;
//Initializer list allows fields to be defined
//before the constructor body.
//This is required for final fields.
Position(int x, int y)
: this.x = x,
this.y = y,
rad = atan2(y, x);
//Getter
double get rad => rad
// ^^^ used to return value
//Setter
void set x(int val) {
// ^^^ used to return value
_x = val;
}
}
main(){
var p = new Position(2,3); //Position object gets created
}
inheritance
//Abstract classes cannot be instantiated
// It can contain some implementation though
abstract class Animal {
String name;
Animal(this.name);
String get noise;
}
class Dog extends Animal {
// ^^^^^^ used to exten the animal class with new
Dog(String name): super(name);
String get noise => 'bark!';
}
class Pikachu implements Animal {
// ^^^^^ used to implement the Animal class
String name = Pikachu;
String get noise => 'pika!';
}
mixins
import `dart:math`;
class Position {
int x;
int y;
double distanceTo(Position other) {
var dx = other.x - x;
var dy = other.y - y;
return sqrt(dx*dx + dy*dy);
}
}
class Square {
int width;
int height;
int get area => width*height;
}
main(){
}