Tworzenie aliasów wartości wyliczeniowych wewnątrz ich deklaracji

0

Mam dość nietypowe pytanie, odnośnie deklaracji typów wyliczeniowych. Mały przykład, ilustrujący takie pseudo-aliasy:

type
  TOptionKind = (okCancel, okFirst, okYes = 1, okSecond, okNo = 2, okThird);

Kompilator bez problemu kompiluje taki kod, dodając do okna wiadomości notkę:

Note: Values in enumeration types have to be ascending

Czyli małym problemem jest to, że typ ten reprezentuje ciąg niemalejący zamiast rosnącego.

Pobranie wartości liczbowych za pomocą funkcji Ord działa prawidłowo, porównanie par elementów o takich samych liczbowych wartościach również działa prawidłowo. Jedynym minusem jest to, że pętla for in dla tego typu wykona cztery iteracje – czyli tyle, ile jest unikalych wartości (ale na pętli mi nie zależy), a nie tyle, ile jest faktycznych elementów.


Meritum: Czy używanie takiego typu wyliczeniowego może być w jakiś sposób nieprzewidywalne?

W dokumentacji nie znalazłem informacji na ten temat, ani też żadnych kodów wykorzystujących tak zadeklarowany typ wyliczeniowy. Dlatego też nie wiem czy uznać zdolność kompilacji tego kodu za „false positive” i zastąpić go zestawem stałych, czy spokojnie użyć tej konstrukcji, ignorując pokazywaną notkę.

1

nie zadziała (znaczy zadziała ale pominie "duble") Ci oprócz for in jeszcze for x := Low(TOptionKind) to High(TOptionKind) oraz Pred i Succ. Dzieje się tak ponieważ te funkcje operują na wartości liczbowej typu i inkrementują czy też dekrementują ją o jeden bez sprawdzania, czy nie ma typu z taką samą wartością.

Podobnie gdybyś zadeklarował typ tak TOptionKind = (okCancel=2, okNo = 5); to for OptionKind in TOptionKind do IntToStr(Ord(OptionKind )) zwróci wartości 2 3 4 5 ponieważ dla takiej deklaracji tworzone jest 5-2+1 elementów. Poza tym całą reszta działa jak w "normalnych" typach wyliczeniowych

0

Na pętlach mi w ogóle nie zależy i na pewno nie będę potrzebował iterować po wartościach tego typu.

Mam okno dialogowe, w którym są trzy przyciski wyboru oraz standardowy krzyżyk w rogu do anulowania. Wewnątrz klasy okna nie mam wiedzy na temat treści tych przycisków, więc chciałbym posługiwać się enumami w stylu okFirst, okSecond i okThird, czyli numerami przycisków.

Natomiast w metodach konkretyzujących przeznaczenie okna (w stylu MessageBox, tyle że o nazwach np. Question, Information, Warning i Error) wygodniej by mi było, gdybym mógł użyć aliasów typu okCancel, okYes, okNo, okRetry itd. – stąd próba stworzenia aliasów.

abrakadaber napisał(a):

Podobnie gdybyś zadeklarował typ tak TOptionKind = (okCancel=2, okNo = 5); to for OptionKind in TOptionKind do IntToStr(Ord(OptionKind )) zwróci wartości 2 3 4 5 […]

FPC najwyraźniej nieco inaczej podchodzi do tego – taki kod w ogóle nie zostanie skompilowany:

Error: For in loop cannot be used for the type "TOptionKind"

W takim przypadku trzeba użyć Low i High do pozyskania zakresu.

Poza tym całą reszta działa jak w "normalnych" typach wyliczeniowych

W takim razie – skoro nie ma w tym nic nieprzewidywalnego – pozostaje tylko używać. Dziękuję za odpowiedź.

1 użytkowników online, w tym zalogowanych: 0, gości: 1