Partager via


Indications pour la mise en forme du code (F#)

Cette rubrique résume les indications de mise en retrait du code en F#. Le langage F# étant sensible aux sauts de ligne et à la mise en retrait, la mise en forme de votre code ne relève pas seulement d'une question de lisibilité, d'esthétique ou encore de normalisation du codage. Vous devez mettre en forme votre code de façon appropriée pour qu'il se compile correctement.

Règles générales en matière de mise en retrait

Lorsque la mise en retrait est requise, vous devez utiliser des espaces, et non des tabulations. Au moins un espace est requis. Votre organisation peut créer des normes de codage pour spécifier le nombre d'espaces à utiliser pour la mise en retrait ; il est courant d'utiliser trois ou quatre espaces à chaque niveau de mise en retrait. Vous pouvez configurer Visual Studio de manière à ce qu'il se conforme aux normes de mise en retrait de votre organisation en modifiant les options dans la boîte de dialogue Options qui est accessible dans le menu Outils. Dans le nœud Editeur de texte, développez F#, puis cliquez sur Onglets. Pour obtenir une description des options disponibles, consultez Tabulations, Tous les langages, Éditeur de texte, boîte de dialogue Options.

En général, lorsque le compilateur analyse votre code, il gère une pile interne qui indique le niveau actuel d'imbrication. Lorsque le code est mis en retrait, un nouveau niveau d'imbrication est créé, ou fait l'objet d'un push dans cette pile interne. Lorsqu'une construction se termine, le niveau est dépilé. La mise en retrait est un moyen de signaler la fin d'un niveau et de dépiler la pile interne, mais certains jetons provoquent également le dépilement du niveau, par exemple le mot clé end, ou une accolade ou une parenthèse fermante.

Le code dans une construction multiligne, notamment une définition de type, une définition de fonction, une construction try...with et les constructions de bouclage, doit être mis en retrait par rapport à la ligne d'ouverture de la construction. La première ligne mise en retrait établit une position de colonne pour le code suivant dans la même construction. Le niveau de mise en retrait est appelé contexte. La position de la colonne définit une colonne minimale, appelée ligne hors-jeu, pour les lignes de code suivantes qui se trouvent dans le même contexte. Lorsque le compilateur rencontre une ligne de code qui est insuffisamment mise en retrait par rapport à la position de colonne établie, il présume que le contexte s'est terminé et que vous codez maintenant au niveau supérieur, dans le contexte précédent. Le terme hors-jeu est utilisé pour décrire la condition dans laquelle une ligne de code déclenche la fin d'une construction parce qu'elle n'est pas suffisamment mise en retrait. En d'autres termes, le code à gauche d'une ligne hors-jeu est hors-jeu. Dans le code correctement mis en retrait, vous pouvez mettre à profit la règle de hors-jeu pour définir la fin de constructions. Si vous utilisez la mise en retrait de manière incorrecte, une condition de hors-jeu peut contraindre le compilateur à émettre un avertissement ou entraîner une mauvaise interprétation de votre code.

Les lignes hors-jeu sont déterminées comme suit.

  • Un jeton = associé à let introduit une ligne hors-jeu au niveau de la colonne du premier jeton après le signe =.

  • Dans une expression if...then...else, la position de la colonne du premier jeton après le mot clé then ou le mot clé else introduit une ligne hors-jeu.

  • Dans une expression try...with, le premier jeton après try introduit une ligne hors-jeu.

  • Dans une expression match, le premier jeton après with et le premier jeton après chaque -> introduisent des lignes hors-jeu.

  • Le premier jeton après with dans une extension de type introduit une ligne hors-jeu.

  • Le premier jeton après une accolade ou une parenthèse ouvrante, ou après le mot clé begin, introduit une ligne hors-jeu.

  • Le premier caractère dans les mots clés let, if et module introduisent des lignes hors-jeu.

Les exemples de code suivants illustrent les règles de mise en retrait. Ici, les instructions print dépendent de la mise en retrait pour les associer au contexte approprié. Chaque fois que la mise en retrait est décalée, le contexte est dépilé et retourne au contexte précédent. Par conséquent, un espace est imprimé à la fin de chaque itération ; « Terminé ! » est imprimé uniquement une fois parce que la mise en retrait hors-jeu établit qu'il ne fait pas partie de la boucle. L'impression de la chaîne « Top-level context » ne fait pas partie de la fonction. Par conséquent, elle est imprimée en premier, au cours de l'initialisation statique et avant que la fonction ne soit appelée.

let printList list1 =
    for elem in list1 do
        if elem > 0 then
            printf "%d" elem
        elif elem = 0 then
            printf "Zero"
        else
            printf "(Negative number)"
        printf " "
    printfn "Done!"
printfn "Top-level context."
printList [-1;0;1;2;3]

La sortie est la suivante.

Top-level context

(Negative number) Zero 1 2 3 Done!

Lorsque vous coupez de longues lignes, la continuation de la ligne doit être en retrait par rapport à la construction englobante. Par exemple, les arguments de fonction doivent être plus en retrait que le premier caractère du nom de fonction, comme indiqué dans le code suivant.

let myFunction1 a b = a + b
let myFunction2(a, b) = a + b
let someFunction param1 param2 =
    let result = myFunction1 param1
                     param2
    result * 100
let someOtherFunction param1 param2 =
    let result = myFunction2(param1,
                     param2)
    result * 100

Ces règles sont soumises à des exceptions, comme décrit dans la section suivante.

Mise en retrait dans les modules

Le code dans un module local doit être mis en retrait par rapport au module, mais il n'est pas nécessaire de mettre en retrait le code dans un module de niveau supérieur. Il est inutile de mettre en retrait les éléments d'espace de noms.

Les exemples de code suivants illustrent ceci.

// Program1.fs
// A is a top-level module.
module A

let function1 a b = a - b * b
// Program2.fs
// A1 and A2 are local modules.
module A1 =
    let function1 a b = a*a + b*b

module A2 =
    let function2 a b = a*a - b*b

Pour plus d'informations, consultez Modules (F#).

Exceptions aux règles de mise en retrait de base

Selon la règle générale, décrite dans la section précédente, le code dans les constructions multilignes doit être mis en retrait par rapport à la mise en retrait de la première ligne de la construction, et la fin de la construction est déterminée par la première ligne hors-jeu. Il existe toutefois une exception à la règle de fin des contextes. En effet, certaines constructions, par exemple l'expression try...with, l'expression if...then...else et l'utilisation de la syntaxe and pour déclarer des fonctions ou des types mutuellement récursifs, ont plusieurs parties. Vous mettez en retrait les dernières parties, telles que then et else dans une expression if...then...else, au même niveau que le jeton qui démarre l'expression, mais au lieu d'indiquer une fin au contexte, vous indiquez la partie suivante du même contexte. Par conséquent, une expression if...then...else peut être écrite comme dans l'exemple de code suivant.

let abs1 x =
    if (x >= 0)
    then
        x
    else
        -x

L'exception à la règle de hors-jeu s'applique uniquement aux mots clés else et then. Par conséquent, si le fait de mettre davantage en retrait then et else ne constitue pas une erreur, un avertissement est généré si vous ne mettez pas en retrait les lignes de code dans un bloc then. Ceci est illustré dans les lignes de code suivantes.

// The following code does not produce a warning.
let abs2 x =
    if (x >= 0)
        then
        x
        else
        -x
// The following code is not indented properly and produces a warning.
let abs3 x =
    if (x >= 0)
    then
    x
    else
    -x

Pour le code dans un bloc else, une règle spéciale supplémentaire s'applique. L'avertissement dans l'exemple précédent se produit uniquement sur le code dans le bloc then, et non sur le code dans le bloc else. Cela vous permet d'écrire du code qui vérifie différentes conditions au début d'une fonction sans forcer la mise en retrait du reste du code pour la fonction, qui peut être dans un bloc else. Vous pouvez donc écrire le code suivant sans générer d'avertissement.

let abs4 x =
    if (x >= 0) then x else
    -x

Il existe une autre exception à la règle selon laquelle les contextes se terminent lorsqu'une ligne n'est pas autant mise en retrait qu'une ligne précédente. Celle-ci concerne les opérateurs infixes, tels que + et |>. Les lignes qui commencent par des opérateurs infixes sont autorisées à commencer des colonnes (1 + oplength) avant la position normale, sans déclencher la fin du contexte, où oplength est le nombre des caractères qui composent l'opérateur. Dans ce cas, le premier jeton après l'opérateur est aligné avec la ligne précédente.

Par exemple, dans le code suivant, le symbole + est autorisé à être mis en retrait à deux colonnes de moins que la ligne précédente.

let function1 arg1 arg2 arg3 arg4 =
    arg1 + arg2
  + arg3 + arg4

Bien que la mise en retrait augmente généralement à mesure que le niveau d'imbrication croît, le compilateur vous permet de réinitialiser la mise en retrait à une position de colonne inférieure dans plusieurs constructions.

Les constructions qui autorisent une réinitialisation de position de colonne sont les suivantes :

  • Corps de fonctions anonymes Dans le code suivant, l'expression print commence à une position de colonne qui est plus à gauche que le mot clé fun. Toutefois, la ligne ne doit pas commencer à une colonne à gauche du début du niveau de mise en retrait précédent (autrement dit, à gauche de L dans List).

    let printListWithOffset a list1 =
        List.iter (fun elem ->
            printfn "%d" (a + elem)) list1
    
  • Constructions entre parenthèses ou entre begin et end dans un bloc then ou else d'une expression if...then...else, à condition que la mise en retrait ne soit pas inférieure à la position de la colonne du mot clé if. Cette exception autorise un style de programmation dans lequel une parenthèse ouvrante ou begin est utilisé à la fin d'une ligne après then ou else.

  • Corps de modules, classes, interfaces et structures délimités par begin...end, {...}, class...end ou interface...end. Ceci autorise un style dans lequel le mot clé ouvrant d'une définition de type peut être sur la même ligne que le nom de type, sans forcer le corps entier à être mis davantage en retrait par rapport au mot clé d'ouverture.

    type IMyInterface = interface
       abstract Function1: int -> int
    end
    

Voir aussi

Autres ressources

Référence du langage F#