Pattern

I. Motif OU logique A || B

Correspond à n’importe quel sous-motif ; toutes les branches doivent définir exactement le même ensemble de variables.

enum Color { red, yellow, blue, green }
void main() {
  Color c = Color.red;
  bool primary = switch(c) {
    Color.red || Color.yellow || Color.blue => true,
    _ => false
  };
  print(primary); // true
}Langage du code : Dart (dart)

II. Motif ET logique A && B

Les deux sous-motifs doivent correspondre simultanément ; les sous-motifs ne peuvent pas lier des variables portant le même nom.

void main() {
  switch((2, 3)) {
    // Erreur : les deux sous-motifs lient la variable b, conflit de noms
    // case (var a, var b) && (var b, var c): print("ok");
    case (var a, var b) && (>1, <5):
      print("a=$a,b=$b"); // a=2,b=3
  }
}Langage du code : Dart (dart)

Ici le motif (>1, <5) impose que le premier nombre soit supérieur à 1 et le second inférieur à 5.

III. Motif relationnel < > <= >= == !=

Utilisé pour vérifier des intervalles numériques, souvent associé à && pour restreindre une plage de valeurs

String asciiCharType(int charCode) {
  const space = 32, zero = 48, nine = 57;
  return switch(charCode) {
    < space => "Caractère de contrôle",
    == space => "Espace",
    > space && < zero => "Ponctuation",
    >= zero && <= nine => "Chiffre",
    _ => "Autre"
  };
}
void main() {
  print(asciiCharType(50)); // Chiffre
  print(asciiCharType(33)); // Ponctuation
}Langage du code : Dart (dart)

Cet exemple utilise le code ASCII pour représenter les caractères de contrôle, les chiffres et les symboles. Le paramètre charCode du switch suit ces règles : inférieur à 32 = caractère de contrôle, égal à 32 = espace, entre 32 et 48 = ponctuation, de 48 à 57 inclus = chiffre, tout le reste est classé comme autre.

IV. Motif de cast de type sub as Type

Conversion de type forcée au milieu d’une décomposition ; une exception d’exécution est levée si le type ne correspond pas

void main() {
  (num, Object) rec = (10, "hello");
  var (i as int, s as String) = rec;
  print(i + 5); // 15
  print(s.toUpperCase()); // HELLO
}Langage du code : Dart (dart)

Dans cet exemple, l’enregistrement rec est décomposé en i et s. Si le premier élément n’est pas un entier ou le second pas une chaîne de caractères, une exception est levée à l’exécution.

Voir l’exemple défectueux ci-dessous :

void main() {
  (num, Object) rec = (9.3, "hello");
  var (i as int, s as String) = rec;
  print(i + 5); // 15
  print(s.toUpperCase()); // HELLO
}Langage du code : Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
type 'double' is not a subtype of type 'int' in type cast
#0      main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:3:10)
#1      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Langage du code : PHP (php)

V. Motif de vérification null sub?

Ne correspond que si la valeur n’est pas null ; les variables internes sont automatiquement promues en type non nullable. Une valeur null échoue la correspondance sans lever d’erreur.

void main() {
  String? str = "test";
  switch(str) {
    case var s?:
      print(s.length); // s est une chaîne non nullable, affiche 4
    case null:
      print("Valeur nulle");
  }
}Langage du code : Dart (dart)

VI. Motif d’assertion non null sub!

Ne correspond que si la valeur n’est pas null ; si la valeur est null, une exception d’exécution est immédiatement levée

void main() {
  List<String?> row = ["user", "bob"];
  switch(row) {
    case ["user", var name!]:
      print(name); // name est une chaîne non nullable
  }

  // Utilisation dans la décomposition de variables
  (int?, int?) pos = (2, 3);
  var (x!, y!) = pos;
  print(x + y);
}Langage du code : Dart (dart)

Décomposition de var name!

  • var name : Motif de variablevar déclare une nouvelle variable locale name et lui associe la valeur si la correspondance réussit ;
  • ! : Motif d’assertion null postfixé — impose que la valeur ne soit pas null ; une erreur survient à l’exécution si c’est le cas.

Sens combiné : var name! crée une nouvelle variable name et affirme simultanément que sa valeur ne peut pas être null.

VII. Motif de constante

Les littéraux, constantes nommées, constructeurs const et collections const sont tous des motifs de constante ; il y a correspondance si les valeurs sont identiques

Types pris en charge : nombres, chaînes, booléens, constantes nommées, objets / listes const

void main() {
  const target = 10;
  int num = 10;
  switch(num) {
    case 1: print("Un");
    case target: print("Correspond à la constante 10");
    case const [1,2]: print("Liste constante");
    default: print("Autre");
  }
}Langage du code : Dart (dart)

Résultat de l’exécution

Correspond à la constante 10

VIII. Motif de variable var x / int x / final x

Associe une nouvelle variable locale quand la correspondance réussit ; une annotation de type ajoute une vérification de type simultanée

void main() {
  switch((99, "dart")) {
    case (int a, String b):
      print("$a $b"); // 99 dart
    case (int a, int b):
      print("Deux valeurs numériques");
  }
}Langage du code : Dart (dart)

IX. Motif d’identifiant

Trois comportements selon le contexte :

  1. Contexte de déclaration var (a,b) : crée de nouvelles variables
  2. Contexte d’affectation (a,b) = val : remplace les variables existantes
  3. Contexte de correspondance switch : traité comme une constante (sauf _)
void main() {
  const c = 5;
  int val = 2;
  switch(val) {
    case c: print("Correspond à la constante c");
    default: print("Aucune correspondance"); // Cette ligne s'exécute
  }
}
Langage du code : Dart (dart)

X. Motif parenthésé (sousMotif)

Modifie la priorité des opérateurs de motif pour clarifier l’ordre d’évaluation entre || et &&

void main() {
  bool x = true, y = true, z = false;
  bool test = switch(true) {
    (x || y) && z => true,
    _ => false
  };
  print(test); // false
}
Langage du code : Dart (dart)

XI. Motif de liste

Correspond à une liste et décompose ses éléments par position ; supporte l’opérateur rest ... pour capturer un nombre quelconque d’éléments restants

1. Correspondance de liste basique
void main() {
  const a = "a", b = "b";
  var arr = ["a", "b"];
  switch(arr) {
    case [a, b]: print("Correspondance trouvée");
    default: print("Aucune correspondance");
  }
}Langage du code : Dart (dart)
2. Capture des éléments restants avec rest
void main() {
  var [a, b, ...rest, c, d] = [1,2,3,4,5,6,7];
  print("$a $b $rest $c $d"); // 1 2 [3, 4, 5] 6 7
}
Langage du code : Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
1 2 [3, 4, 5] 6 7Langage du code : CSS (css)

XII. Motif de Map {"clé": sousMotif}

Correspond à un Map et ne valide que les clés spécifiées ; une clé manquante lève une erreur StateError, les clés supplémentaires sont ignorées

void main() {
  var data = {"user": ["Lily", 13]};
  if(data case {"user": [String name, int age]}) {
    print("$name $age"); //Lily 13
  }
}Langage du code : JavaScript (javascript)

XIII. Motif d’enregistrement

Deux variantes : enregistrement positionnel (p1,p2), enregistrement nommé (k:p1,k2:p2)

Prend en charge la syntaxe abrégée :var pour omettre les noms de champs répétés

void main() {
  // Décomposition d'enregistrement positionnel
  var (name, age) = ("Doug", 25);
  // Décomposition abrégée des champs nommés
  final (:name, :age) = (name: "Tom", age: 18);
}
Langage du code : JavaScript (javascript)

XIV. Motif d’objet Classe(propriété: sousMotif)

Correspond à un objet du type indiqué et décompose les propriétés getter ; syntaxe abrégée :var disponible

class Point {
  final int x, y;
  Point(this.x, this.y);
}

void main() {
  Point p = Point(10, 20);
  var Point(:x, :y) = p;
  print("$x $y");
}
Langage du code : JavaScript (javascript)

XV. Motif générique (joker) _

Correspond à n’importe quelle valeur sans lier de variable ; utilisé comme espace réservé ou pour vérifier un type sans récupérer la valeur

void main() {
  var arr = [1,2,3];
  var [_, mid, _] = arr;
  print(mid); // 2

  switch((10, "abc")) {
    case (int _, String _):
      print("Correspondance de type réussie");
  }
}Langage du code : JavaScript (javascript)

Pattern

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *