Rekord z wariantami

Rekord z wariantami jest to rodzaj rekordu, posiadającego tę właściwość, że zbiór rekordów posiada wspólny typ, lecz różną postać, określoną aktualną wartością specjalnego pola znacznikowego.

Pola wariantowe

Rekord jest strukturą, agregatem danych, składającą się z pól rozmieszczonych kolejno w pamięci, zgodnie z deklaracją rekordu. W przypadku rekordu z wariantami, część pól – a konkretnie pól wariantowych – może być rozmieszczona w pamięci począwszy od tego samego adresu pamięci. Pola te (lub grupy pól stanowiące jeden z wariantów), mogą być różnego typu.

Przykład w języku Pascal:

 type adres=record
   kod : string[6];
   poczta : string[30];
   case wies : Boolean of
     True : (nazwa : string[25]; numer : integer);
     False: (ulica : string[30]; numer : integer
             mieszkanie : integer);
 end;
  • Jeżeli adres dotyczy wsi (wartość pola wies=True), to rekord składał się będzie z pól: kod, poczta, wies, nazwa, numer;
  • Jeżeli adres dotyczy miasta (wartość pola wies=False), to rekord składał się będzie z pól: kod, poczta, wies, ulica, numer, mieszkanie;

przy czym pole nazwa i ulica zlokalizowane będą w pamięci począwszy od tego samego adresu pamięci operacyjnej.

Pole znacznikowe

Wartość pola znacznikowego określa jaką postać ma aktualnie rekord, tzn. które pola wariantowe posiadają rzeczywiście, aktualnie, przypisaną prawidłową wartość. Pole znacznikowe może być polem anonimowym, tzn. nie posiadać jawnie określonej nazwy (tak może być np. w języku Pascal), ew. może być w ogóle niedostępne dla programisty (np. Algol 68), w rekordach z wariantami zawsze jednak takie pole występuje.

Porównanie z innymi konstrukcjami

Warianty zawarte w rekordzie są podobne do unii (np. język C). Rekord wariantowy, składający się tylko z wariantów (bez pól poza wariantami), różni się od unii w zasadzie tylko występowaniem pola znacznikowego. Tak więc w unii wszystkie pola rozmieszczone są począwszy od tego samego adresu, a w rekordzie z wariantami mogą występować pola zwykłe rekordu, oraz pola wariantowe zawsze poprzedzone polem znacznikowym. Unię można uznać za odpowiednik rekordu z wariantami w językach niższego rzędu. Powyższe uwagi dotyczą także analogii jaką można dostrzec w odniesieniu do grupy deklaracji zmiennych rozmieszczonych przez programistę w pamięci począwszy od tego samego adresu (np. dyrektywą absolute w Turbo Pascalu).

Porównując rekordy z wariantami i „typ wariantowy”, występujący w niektórych językach programowania (np. Visual Basic), należy zauważyć, że

  • w typie wariantowym nie ma ograniczeń co do typu przypisywanych wartości, a w rekordzie z wariantami można przypisywać polom, tylko wartości typu zdefiniowanego w deklaracji rekordu, a więc lista typów jest ograniczona,
  • struktura i implementacja typu wariantowego jest ukryta, przy rekordach z wariantami implementacja należy do programisty.
  • typ wariantowy pojawia się przeważnie w językach o słabej typizacji, rekord wariantowy – silnej.

Przykłady

Ada

  record
    pola ...;
    [case wyróżnik is
      when wartość_1 => pola_wariantowe_1
      ...
      when wartość_n => pola_wariantowe_n
    end case;]
    [...
     pola
     [case wyróżnik is
       when wartość_1 => pola_wariantowe_1
       ...
       when wartość_n => pola_wariantowe_n
     end case;<code>]]</code>
    [...]
  end record;

Algol 68

Istnieje możliwość deklarowania unii (w rzeczywistości rekordów z wariantami) wyłącznie z pól całkowitych i logicznych, a pole znacznikowe jest ukryte, obsługa następuje automatycznie.

Modula 2

 RECORD
   pola ...
   [CASE pole_znacznikowe OF
     pola_wariantowe
   END]
   [pola ...
   [CASE pole_znacznikowe OF
     pola_wariantowe
   END]]
   [...]
 END

W Moduli 2 mogą występować wielokrotne pola wariantowe w tym samym rekordzie.

Pascal

  record
    pola ...;
    [case [pole_znacznikowe:]typ_porządkowy of
      wartość_1 : (pola_warianotwe_1);
      ...
      wartość_n : (pola_warianotwe_n);
  end;

Może wystąpić tylko jedna sekcja wariantowa na końcu rekordu.

Bibliografia