Énumération

I. Types énumérés (Enumerated Type)

Les énumérations Pascal sont des types opaques à très bonne encapsulation ; on les utilise bien plus souvent en développement quotidien que les énumérations des autres langages.

Syntaxe de définition basique

type
  TAnimalKind = (akDuck, akCat, akDog);

Règle de nommage : ajouter un préfixe deux lettres abrégé du type sur chaque constante d’énumération

  • ak = Animal Kind (abréviation de TAnimalKind)
  • Intérêt : les constantes d’énumération se trouvent par défaut dans l’espace de noms global de l’unité. Le préfixe limite drastiquement les conflits de nom avec les autres variables et types.

Le T au début de TAnimalKind est syntaxiquement optionnel, c’est juste une convention professionnelle. On recommande de le garder, car on voit immédiatement qu’il s’agit d’un type énuméré.

type
  AnimalKind = (akDuck, akCat, akDog); // Sans T, syntaxe autoriséeLangage du code : JavaScript (javascript)

Précisions complémentaires :

  1. Deux identifiants identiques ne déclenchent pas d’erreur de compilation ; des unités différentes peuvent porter des noms identiques ;
  2. Cependant, pour la lisibilité du code et les recherches globales (grep), il vaut mieux éviter volontairement les conflits de nommage.

Énumérations à portée limitée (énumérations qualifiées, {$scopedenums on})

La directive compilateur {$scopedenums on} isole les constantes d’énumération à l’intérieur du type correspondant, sans polluer l’espace de noms global

Désactivé par défaut
{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
program EnumDemo;

type TAnimalKind = (akDuck, akCat);

var k: TAnimalKind;

begin
  k := akDuck; // Utilisation directe de la constante, sans TAnimalKind.
  WriteLn(k); //Affiche akDuck
end.Langage du code : PHP (php)

Comme nous l’avons vu précédemment, l’exécution du code commence au mot-clé begin.

Ajouter le préfixe ak est une bonne pratique pour éviter les conflits ; l’omettre ne provoque pas d’erreur pour autant.

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}

program EnumDemo;

type TAnimalKind = (Duck, Cat);

var k: TAnimalKind;

begin
  k := Duck; 
  WriteLn(k);//Duck
end.Langage du code : PHP (php)

Avec {$scopedenums on}, il faut systématiquement écrire « NomDuType. »

  1. Tout accès doit être qualifié par le type : TAnimalKind.akDuck
  2. Le préfixe ak devient inutile ; les constantes peuvent s’écrire simplement Duck, Cat, Dog
{$scopedenums on}
type
  TAnimalKind = (Duck, Cat, Dog);
var
  Kind: TAnimalKind;
begin
  Kind := TAnimalKind.Duck; // Qualificateur de type obligatoire
end;Langage du code : PHP (php)

Si on omet le qualificateur de type

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
{$scopedenums on}
program EnumDemo;

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := Duck; // Sans TAnimalKind.
  WriteLn(k);
end.Langage du code : PHP (php)

Erreur de compilation générée

D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
mydemo.dpr(9,8) Error: Identifier not found "Duck"
mydemo.dpr(11,4) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: C:\FPC\3.2.2\bin\i386-Win32\ppc386.exe returned an error exitcodeLangage du code : CSS (css)

Si on ajoute le qualificateur ensuite

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
{$scopedenums on}
program EnumDemo;

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := TAnimalKind.Duck; // Avec TAnimalKind.
  WriteLn(k);
end.Langage du code : PHP (php)

La compilation fonctionne normalement

Conversion forcée entre énumérations et entiers

Les énumérations sont des types opaques ; on ne peut pas affecter directement des entiers et des énumérations entre eux, une conversion forcée manuelle est obligatoire :

  1. Énumération → Entier : Ord(variable_énum)
  2. Entier → Énumération : conversion de type explicite TAnimalKind(valeur_entier)
  3. Vérifiez toujours l’intervalle avant de convertir un entier en énumération : plage valide 0 ~ Ord(High(TypeÉnum))
type
  TAnimalKind = (akDuck, akCat, akDog);
var
  Kind: TAnimalKind;
  Num: Integer;
begin
  Kind := akCat;
  Num := Ord(Kind); // akCat a pour rang 1, Num=1

  Num := 2;
  // Vérifier la validité de la valeur avant conversion
  if (Num >= 0) and (Num <= Ord(High(TAnimalKind))) then
    Kind := TAnimalKind(Num);
end;Langage du code : JavaScript (javascript)
{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}

program EnumDemo;

type
  TAnimalKind = (akDuck, akCat, akDog);
var
  Kind: TAnimalKind;
  Num: Integer;
begin
  Kind := akCat;
  Num := Ord(Kind); // akCat index is 1,Num=1

  Num := 2;

  if (Num >= 0) and (Num <= Ord(High(TAnimalKind))) then
    Kind := TAnimalKind(Num);

  WriteLn(Num);//2
end.Langage du code : PHP (php)

Laisser un commentaire

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