Irbisa · Cheatsheet
Advanced Dart
Generics, extensions, mixins, isolates, dart:core advanced
What is an isolate in Dart, and when should you move work into one?
import 'dart:convert';import 'dart:isolate'; class User { final String name; User(this.name);…What does the
latemodifier actually do, and when is it the wrong tool?class _EditorState extends State<Editor> with SingleTickerProviderStateMixin { // lazy: the initializer needs `this`, so it runs on first read late final AnimationController _anim = AnimationController( vsync: this, duration: const Duration(milliseconds: 200),…A crash report says
Bad state: No elementand points at afirstWherecall. What happened and what do you write instead?import 'package:collection/collection.dart'; class Order { final bool isPending; final int cents; const Order(this.isPending, this.cents);…How do generics and type bounds work in Dart, and why do reusable widgets and data classes need them?
// A bound lets the body call compareTo on TT maxOf<T extends Comparable<T>>(List<T> xs) => xs.reduce((a, b) => a.compareTo(b) >= 0 ? a : b); // A generic function: T is fixed per callT first<T>(List<T> xs) => xs.first;…Find the bug:
markSeenthrows at run time instead of remembering that the photo was seen.class Photo { Photo(this.id); final int id; }class Meta { bool seen = false; } // Per-photo UI flags without touching Photo.final _meta = Expando<Meta>('photoMeta'); void markSeen(Photo photo) { final meta = _meta[photo.id] ?? Meta(); meta.seen = true; _meta[photo.id] = meta;} void main() { markSeen(Photo(7)); print('marked');}Extension methods: what does this program print, and what single rule explains all four lines?
class Animal {}class Dog extends Animal {}extension AnimalX on Animal { String speak() => 'animal'; }extension DogX on Dog { String speak() => 'woof'; } class Cat { String speak() => 'meow'; }extension CatX on Cat { String speak() => 'purr'; } void main() { final Animal a = Dog(); print(a.speak()); print(Dog().speak()); print(Cat().speak()); final dynamic d = Dog(); print(d.speak());}Why does
list.map(...)run nothing until you calltoList(), and when does that laziness bite?void main() { final nums = [1, 2, 3]; final doubled = nums.map((n) { print('mapping $n'); // does not run yet return n * 2;…What are
sync*andasync*generators, and when would you write one?// sync*: values are produced only as the caller asks for themIterable<int> naturals() sync* { var n = 0; while (true) { yield n++; // naturals().take(3) gives 0, 1, 2 }…What does this program with a
sync*generator print?Iterable<int> count() sync* { print('start'); for (var i = 1; i <= 3; i++) { print('yield $i'); yield i; } print('end');} void main() { final numbers = count(); print('created'); print(numbers.first); print(numbers.first);}What are
Uint8Listand the other typed-data lists, and when do you use them instead ofList<int>?import 'dart:typed_data'; void main() { final bytes = Uint8List(4); bytes[0] = 300; print(bytes[0]); // 44: only the low 8 bits are kept…Find the bug:
byId[selected.id]printsnullalthoughselectedcomes from the very same list of rows.class Row { Row(this.id, this.text); final int id; final String text;} var _nextId = 0;Row _toRow(String line) => Row(_nextId++, line); void main() { final rows = ['a', 'b', 'c'].map(_toRow); final selected = rows.first; final byId = {for (final r in rows) r.id: r}; print(byId[selected.id]?.text);}What happens between your Dart source and a release binary (kernel,
gen_snapshot, tree shaking)?How does Dart's garbage collector work (young and old generation), and what does it mean for Flutter code?
Does Dart have reflection? Why is
dart:mirrorsunavailable in Flutter, and what do you use instead?How do
WeakReferenceandExpandolet the GC reclaim cached objects, and why is aFinalizernot a destructor?class DecodedImage { DecodedImage(this.bytes); final int bytes; } // a cache the garbage collector is allowed to emptyclass ThumbCache { final _entries = <String, WeakReference<DecodedImage>>{};…