Typ wyliczeniowy


Typ wyliczeniowy definiuje uporządkowany zbiór wartości, przez proste wyliczenie identyfikatorów oznaczających te wartości. Wartości nie mają ściśle określonego znaczenia, a ich uporządkowanie jest zgodne z kolejnością identyfikatorów wymienionych w liście.

Składnia deklaracji typu wyliczeniowego:

type typeName = (val1, ..., valn)

gdzie typeName i valx są formalnie poprawnym identyfikatorem. Np. deklaracja:

type Kolor = (Kier, Karo, Trefl, Pik);

definiuje typ wyliczeniowy Kolor o dozwolonych wartościach Kier, Karo, Trefl i Pik.

Jednocześnie z deklaracją typu wyliczeniowego, automatycznie deklarowane są valx jako stałe typu typeName. Stąd konieczność używania unikalnych identyfikatorów występujących w tym samym zakresie programu. Np. masz zamiar zadeklarować następujący typ:

type TSound = (Click, Clack, Clock);

Jak się okazuje, identyfikator Click jest już używany jako nazwa metody w obiekcie TControl i wszystkich obiektach w VCL Delphi pochodzących od niego. Jeśli zostanie utworzona procedura obsługi zdarzenia:

procedure TForm1.DBGrid1Enter(Sender: TObject);
var Thing: TSound;
begin
  ...
  Thing := Click;
  ...
end;

będzie to skutkować zgłoszeniem błędu kompilatora; kompilator interpretuje Click wewnątrz procedury jako odwołanie do metody Click obiektu klasy TForm. Można obejść ten problem poprzez kwalifikację identyfikatora; a więc, jeśli TSound zadeklarowano w module MyUnit, można użyć zapisu:

Thing := MyUnit.Click;

Jednak lepszym rozwiązaniem jest stosowanie unikalnych identyfikatorów. Przykłady (zgodne z konwencją nazewnictwa Delphi):

type
  TSound = (tsClick, tsClack, tsClock);
  TMyColor = (mcRed, mcBlue, mcGreen, mcYellow, mcOrange);
  Answer = (ansYes, ansNo, ansMaybe);

Można używać zapisu (val1, ..., valn) wprost w deklaracjach zmiennych:

var MojaKarta: (Kier, Karo, Trefl, Pik);

Lecz ten sposób uniemożliwia deklarowanie innych zmiennych tego samego typu w tym zakresie programu. Zapis:

var Karta1: (Kier, Karo, Trefl, Pik);
var Karta2: (Kier, Karo, Trefl, Pik);

generuje bład kompilatora wynikający z konfliktu nazw. Lecz zapis:

var Karta1, Karta2: (Kier, Karo, Trefl, Pik);

jest poprawny i jednoznaczny z zapisem:

type Suit = (Kier, Karo, Trefl, Pik);
var
  Karta1: Suit;
  Karta2: Suit;