dart

logo


Dart?

  • Object-oriented
  • null-safe
  • JIT compiled beim Debuggen
  • AOT compiled beim Release

Basics

int x = 3;
print('x is $x');   // x is 3
assert('${1 + 1}' == '2');
String text = 'same old';   // oder ""
var firstCharacter = text[0];
int.parse('42') // -> 42
3.14159.toStringAsFixed(2) // -> '3.14'
var list = [1, 2, 3];
List<int> numbers = [...list, 4];
var set = {0};
set.add(0);
assert(set.length == 1);
var frameworkByDeveloper = {
        'Flutter': 'Google', 
        'React Native': 'Meta'
        };
assert(frameworkByDeveloper['Flutter'] == 'Google');
assert(frameworkByDeveloper['Ionic'] == null);

Null Safety

String txt = null;          // 🚫
String? txt = null;         // Type? ist nullable
var firstChar = txt[0];     // 🚫
var firstChar = txt![0];    // ! -> es IST nicht null

Functions

bool isEven(int n) {
    return n % 2 == 0;
}
bool isOdd(int n) => n % 2 != 0;
Map<int, String>? _onlyForInternalUse(noType) {
    return null;
}

assert(_onlyForInternalUse(42) == null);

Named/Optional Parameters

void format(String text, {String direction='ltr', bool? bold}) 

format('text', bold: null);
format('text');
format('text', bold: false, direction:'rtl');
String substring(int start, [int? end])

XOR

void foo(int i, {String? txt}, [bool b]);   // 🚫

Operatoren

assert(12 / 10 == 1.2);
assert(12 ~/ 10 == 1);
a ?? b == (a != null ? a : b)
Object? x = null;
42 ?? 'only if null';  // -> 42
x ?? 42;               // -> 42
o?.x == (o != null ? o.x : null)
userObject?.userName?.toString()

Loops

var evens = [0, 2, 4];
for (final n in evens) {
  print(n);
}
evens.forEach((n) => print(n));     // Dart: avoid
evens.forEach(print);

λ

List.generate(10, (i) => i + 1)
    .where((i) => i % 2 == 1)
    .take(3)
    .map((i) => '-' * i)
    .forEach(print);

OOP

class Person {
  String name = 'required';
  int? _age;  // not required
  
  Person(this.name, this._age);
  
  set age(int age) {
    if (age < 0) 
      throw 'Invalid age: $age';
    _age = age;
  }
  
  @override
  bool operator == (Object other) {
      identical(this, other) || other is Person &&
              runtimeType == other.runtimeType &&
              name == other.name && _age == other._age;
  }
  
  @override
  String toString() {
    return '$name, $_age';
  }

}

Inheritance

class Animal {
    final String name;  // impliziter getter

    void live() => print('living');

    Animal(this.name);
}
class Dog extends Animal{
    Dog(String name) : super(name);
}
class Ant implements Animal {
    @override
    String get name => 'Ant';
    
    @override
    void live() {}
}

Mixins

abstract class Flyer {
    void fly() => print('flying');
    // void abstractMethod();
}
class Duck extends Animal implements Flyer {
    Duck(String name) : super(name);

    @override
    void fly() {
        // Can't extend two classes
        // Have to implement interface (🤮 default 🤮)
        print('flying');
    }
}
class Eagle extends Animal with Flyer {
    Eagle(String name) : super(name);
}

animals


animals


final vs const

class Point {
  static final Point origin = const Point(0, 0);
  final int x;
  final int y;
  const Point(this.x, this.y);
  Point.clone(Point other) : this(other.x, other.y);    // named Constructor
}
  var point = Point(0, 0);
  assert(identical(point, Point.origin));   💥
  const point = Point(0, 0);
  assert(identical(point, Point.origin));   ✔️

final ⟹ Runtime constant

const ⟹ Compile constant


const text = const ['Lorem'];
text.add('ipsum');
var text = const ['Lorem'];
text.add('ipsum');
text = ['Something', 'different'];