Delphi pitfalls: Enumerated types and for loops
Lars Fosdal - 18/Feb/2019
Lars Fosdal - 18/Feb/2019
[SHOWTOGROUPS=4,20]
Not all for loops are created equal.
Consider:
You would expect to see x vary in the order of the values in the list.
However – if x and the values are of an enumerated type, looping the “list”
does NOT loop in the apparent order of the constant, but in the order of the enumerated type declaration, such as it would for any set.
An example:
Для просмотра ссылки Войдиили ЗарегистрируйсяДля просмотра ссылки Войди или Зарегистрируйся hosted by Для просмотра ссылки Войди или Зарегистрируйся
The above code yields
Looping an Enum Set
Looping an Enum Array
Press Enter:
This can be easy to miss, so if loop order is important – make sure you code your enums into an actual array and do not leave them as a set.
[/SHOWTOGROUPS]
Not all for loops are created equal.
Consider:
Код:
for x in [value1, value2, value3]
You would expect to see x vary in the order of the values in the list.
However – if x and the values are of an enumerated type, looping the “list”
does NOT loop in the apparent order of the constant, but in the order of the enumerated type declaration, such as it would for any set.
An example:
Код:
program EnumArrayvsEnumSet;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
TEnum = (plough, foo, bar, wtf);
procedure Output(const aEnum: TEnum);
begin
case aEnum of
wtf:
Writeln('wtf');
plough:
Writeln('plough');
bar:
Writeln('bar');
foo:
Writeln('foo');
else
Writeln('Missed one!');
end;
end;
procedure TestEnumSet;
var
enum: TEnum;
begin
for enum in [wtf, plough, bar, foo] do
Output(enum);
end;
procedure TestEnumArray;
var
enum : TEnum;
enumArray: TArray<TEnum>;
begin
enumArray := [wtf, plough, bar, foo];
for enum in enumArray do
Output(enum);
end;
begin
try
try
Writeln('Declared: TEnum = (plough, foo, bar, wtf)');
Writeln('Test order: [wtf, plough, bar, foo]');
Writeln;
Writeln('Looping an Enum Set');
TestEnumSet;
Writeln;
Writeln('Looping an Enum Array');
TestEnumArray;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
finally
Writeln;
Write('Press Enter:');
Readln;
end;
end.
Для просмотра ссылки Войди
The above code yields
Код:
Declared: TEnum = (plough, foo, bar, wtf)
Test order: [wtf, plough, bar, foo]
Looping an Enum Set
Код:
plough
foo
bar
wtf
Looping an Enum Array
Код:
wtf
plough
bar
foo
Press Enter:
This can be easy to miss, so if loop order is important – make sure you code your enums into an actual array and do not leave them as a set.
[/SHOWTOGROUPS]