Patterns
Dernière mise à jour
Cet article vous a-t-il été utile ?
Dernière mise à jour
Cet article vous a-t-il été utile ?
Patterns = règles pour détecter la structure de données en entrée
Utilisés abondamment en F♯
Dans match expression, let binding de valeurs et de paramètres de fonctions
Très pratiques pour manipuler les types algébriques F♯ (tuple, record, union)
Composables : supporte plusieurs niveaux d'imbrication
Assemblables par ET/OU logiques
Supporte les littéraux : 1.0
, "test"
...
Représenté par _
, seul ou combiné avec un autre pattern
Toujours vrai → A placer en dernier dans une match expression
Toujours chercher en 1er à traiter exhaustivement/explicitement tous les cas
Quand impossible, utiliser alors le _
Détecte constantes, null
et littéraux de nombre, char
, string
, enum
☝ Notes :
Le pattern de Three
est aussi classé en tant que Identifier Pattern 📍
Pour le matching de null
, on parle aussi de Null Pattern
Détecte les cases d'un type union ainsi que leur éventuel contenu
Assigne la valeur détectée à une "variable" pour l'utiliser ensuite
Exemple : variables firstName
et lastName
ci-dessous
Solutions : utiliser 2 variables puis vérifier l'égalité
Plusieurs possibilités :
Pattern "anonyme" du tuple complet
→ Il faut déconstruire tous les champs du tuple.
→ On utilise la virgule ,
pour séparer ces champs.
Pattern d'un seul champ par son nom → Field = value
as
permet de nommer un élément dont le contenu est déconstruit
💡 Marche aussi dans les fonctions :
Permettent de combiner deux patterns (nommés P1
et P2
ci-après)
P1 | P2
→ P1 ou P2. Ex : Rectangle (0, _) | Rectangle (_, 0)
P1 & P2
→ P1 et P2. Utilisé surtout avec 🚀 Active Patterns📍
💡 On peut utiliser la même variable (name
ci-dessous) dans 2 patterns :
Usage des parenthèses ()
pour grouper des patterns, pour gérer la précédence
☝ Note : la ligne ① ne compilerait sans faire () :: tail
💡 Essayer de s'en passer quand c'est possible
Reprennent syntaxe de construction d'un type pour le déconstruire
Cons et List Patterns
Array Pattern
Tuple Pattern
Record Pattern
≃ Inverses de 2 types de construction d'une liste, avec même syntaxe
Cons Pattern : head :: tail
→ décompose une liste (avec >= 1 élément) en :
Head : 1er élément
Tail : autre liste avec le reste des éléments - peut être vide
List Pattern : [items]
→ décompose une liste en 0..N éléments
[]
: liste vide
[x]
: liste avec 1 élément mis dans la variable x
[x; y]
: liste avec 2 éléments mis dans les variables x
et y
[_; _]
: liste avec 2 éléments ignorés
💡 x :: []
≡ [x]
, x :: y :: []
≡ [x; y]
...
La match expression par défaut combine les 2 patterns : → Une liste est soit vide []
, soit composée d'un item et du reste : head :: tail
Les fonctions récursives parcourant une liste utilise le pattern []
pour stopper la récursion :
Syntaxe: [| items |]
pour 0..N items entre ;
☝ Il n'existe pas de pattern pour les séquences, vu qu'elles sont "lazy".
Syntaxe : items
ou (items)
pour 2..N items entre ,
💡 Pratique pour pattern matcher plusieurs valeurs en même temps
Syntaxe : { Fields }
pour 1..N Field = variable
entre ;
Pas obligé de spécifier tous les champs du Record
En cas d'ambiguïté, qualifier le champ : Record.Field
💡 Marche aussi pour les paramètres d'une fonction :
Syntaxe : my-object :? sub-type
Renvoie un bool
→ is
C♯ (my-object is sub-type
)
Usage : avec une hiérarchie de types
try
/with
On rencontre fréquemment ce pattern dans les blocs try
/with
:
Le Type Test Pattern ne marche qu'avec des types références.
→ Pour un type valeur ou inconnu, il faut le convertir en objet (a.k.a boxing)
On ne peut pas lier à plusieurs reprises vers la même variable
Pattern de plusieurs champs par leur nom → F1 = v1; F2 = v2
Ne pas confondre avec l'option 1 :
→ Le délimiteur est ici le point-virgule ;
et non la virgule ,
!
Les parenthèses compliquent la lecture
Rappel : il n'y a pas de pattern pour les Records anonymes !
Remarque : l'opérateur :?
n'est pas conçu pour vérifier des évidences car il adopte alors un comportement déroutant :
(Exemple tiré de cette )