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 variable —vardéclare une nouvelle variable localenameet 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 :
- Contexte de déclaration
var (a,b): crée de nouvelles variables - Contexte d’affectation
(a,b) = val: remplace les variables existantes - 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