Skip to main content

switch

Switch-verklaringen

Een switch-verklaring (Switch Statements) evalueert een waarde-expressie tegen een reeks gevallen (cases). Elke case-clausule is een patroon voor de waarde om tegen te matchen. Je kunt elk soort patroon gebruiken voor een case.

Wanneer de waarde overeenkomt met het patroon van een case, wordt het lichaam van de case uitgevoerd. Niet-lege case-clausules springen na voltooiing naar het einde van de switch. Ze vereisen geen break-verklaring. Andere geldige manieren om een niet-lege case-clausule te beëindigen zijn een continue, throw of return-verklaring.

Gebruik een default- of wildcard _-clausule om code uit te voeren wanneer geen enkele case-clausule overeenkomt:

var x = switch (y) { ... };

print(switch (x) { ... });

return switch (x) { ... };

Als je een switch aan het begin van een expressie-verklaring wilt gebruiken, gebruik dan een switch-verklaring.

Switch-expressies stellen je in staat om een switch-verklaring te herschrijven zoals deze:

// Waar slash, ster, komma, puntkomma, enz., constante variabelen zijn...
switch (charCode) {
  case slash || star || plus || minus: // Logische-of patroon
    token = operator(charCode);
  case comma || semicolon: // Logische-of patroon
    token = punctuation(charCode);
  case >= digit0 && <= digit9: // Relationele en logische-en patronen
    token = number();
  default:
    throw FormatException('Invalid');
}

In een expressie zoals deze:

token = switch (charCode) {
  slash || star || plus || minus => operator(charCode),
  comma || semicolon => punctuation(charCode),
  >= digit0 && <= digit9 => number(),
  _ => throw FormatException('Invalid')
};

Verschillen tussen Switch-expressies en Switch-verklaringen

  • Cases beginnen niet met het sleutelwoord case.
  • Een case-lichaam is een enkele expressie in plaats van een reeks verklaringen.
  • Elke case moet een lichaam hebben; er is geen impliciete fallthrough voor lege cases.
  • Case-patronen worden gescheiden van hun lichamen met => in plaats van :.
  • Cases worden gescheiden door , (en een optionele afsluitende , is toegestaan).
  • Standaard cases kunnen alleen _ gebruiken, in plaats van zowel default als _ toe te staan.

Uitputtingscontrole

Uitputtingscontrole (Exhaustiveness Checking) is een functie die een compile-time fout rapporteert als het mogelijk is dat een waarde een switch binnenkomt, maar geen enkele case matcht.

// Niet-uitputtende switch op bool?, ontbrekende case om de null-mogelijkheid te matchen:
switch (nullableBool) {
  case true:
    print('yes');
  case false:
    print('no');
}

Een default case (default of _) dekt alle mogelijke waarden die door een switch kunnen stromen. Dit maakt een switch op elk type uitputtend.

Enums en verzegelde types (sealed types) zijn bijzonder nuttig voor switches omdat, zelfs zonder een default case, hun mogelijke waarden bekend en volledig opsombaar zijn. Gebruik de sealed-modifier op een klasse om uitputtingscontrole in te schakelen wanneer je over subtypes van die klasse schakelt:

sealed class Shape {}

class Square implements Shape {
  final double length;
  Square(this.length);
}

class Circle implements Shape {
  final double radius;
  Circle(this.radius);
}

double calculateArea(Shape shape) => switch (shape) {
  Square(length: var l) => l * l,
  Circle(radius: var r) => math.pi * r * r
};

Als iemand een nieuwe subklasse van Shape zou toevoegen, zou deze switch-expressie onvolledig zijn. Uitputtingscontrole zou je informeren over het ontbrekende subtype. Dit stelt je in staat om Dart in een enigszins functionele algebraïsche datatype-stijl te gebruiken.

Guard-clausule

Om een optionele guard-clausule (Guard Clause) toe te voegen na een case-clausule, gebruik je het sleutelwoord when. Een guard-clausule kan volgen op if-case en zowel switch-verklaringen als expressies.

Switch-verklaring

switch (something) {
  case somePattern when some || boolean || expression:
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clausule.
    body;
}

Switch-expressie

var value = switch (something) {
  somePattern when some || boolean || expression => body,
  //               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clausule.
};

If-case verklaring

if (something case somePattern when some || boolean || expression) {
  //                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clausule.
  body;
}

Guards evalueren een willekeurige booleaanse expressie na matching. Dit stelt je in staat om verdere beperkingen toe te voegen aan of een case body zou moeten uitvoeren. Wanneer de guard-clausule evalueert naar false, gaat de uitvoering verder naar de volgende case in plaats van de hele switch te verlaten.

Switch-verklaringen en switch-expressies in Dart zijn krachtige hulpmiddelen voor het uitvoeren van verschillende codepaden op basis van de waarde van een enkele variabele. Door het gebruik van cases, defaults, uitputtingscontrole en guard-clausules kun je complexe vergelijkingslogica efficiënt implementeren. Dit maakt je code niet alleen duidelijker en leesbaarder, maar ook robuuster en beter bestand tegen fouten.