Как я не могу посягать собственные авторские права, полный раздел:
Есть несколько мест в Delphi RTL - и много, много мест в Windows API, - где «битмаски» на целое число что-то вроде использования вместо заданных типов. Например, блок System.SysUtils
объявляет функцию, FileGetAttr
, которая возвращает атрибуты файла (только для чтения, скрытые, системные и т. Д.) В виде одного целого. Для проверки отдельных атрибутов, вы должны использовать так называемые «битовые» операторы, в частности and
:
uses
System.SysUtils;
var
Attr: Integer;
begin
Attr := FileGetAttr('C:\Stuff\Some file.txt');
if Attr and faReadOnly <> 0 then
WriteLn('Read only');
if Attr and faHidden <> 0 then
WriteLn('Hidden');
if Attr and faSysFile <> 0 then
WriteLn('System');
end.
Для этой работы, то faXXX
константы определены таким образом, что первый имеет значение 1, второе значение - 2, третье - 4, четвертое - 8 и т. д. Чтобы добавить значение к существующему руководству «набор», используйте or
и удалить значение, используйте and not
:
procedure AddHiddenAttr(const AFileName: string);
begin
FileSetAttr(AFileName, FileGetAttr(AFileName) or faHidden);
end;
procedure RemoveHiddenAttr(const AFileName: string);
begin
FileSetAttr(AFileName, FileGetAttr(AFileName) and not faHidden);
end;
В общем, вы должны использовать соответствующие типы наборов, где вы можете, так как они обеспечивают сильными типизации и большей читаемости. Тем не менее, следующий код демонстрирует тот факт, что под капотом, «настоящие» наборы и их руководство, эквиваленты C-типа сводятся к тому же:
const
mcFirst = 1;
mcSecond = 2;
mcThird = 4;
mcFourth = 8;
type
TMyEnum = (meFirst, meSecond, meThird, meFourth);
TMySet = set of TMyEnum;
var
UsingSet: TMySet;
UsingConsts: LongWord;
begin
//direct assignment
UsingSet := [meSecond, meThird];
UsingConsts := mcSecond or mcThird;
WriteLn('Equal? ', Byte(UsingSet) = UsingConsts);
//subtraction
Exclude(UsingSet, meSecond);
UsingConsts := UsingConsts and not mcSecond;
WriteLn('Equal? ', Byte(UsingSet) = UsingConsts);
//addition
Include(UsingSet, meFourth);
UsingConsts := UsingConsts or mcFourth;
WriteLn('Equal? ', Byte(UsingSet) = UsingConsts);
//membership test
if meThird in UsingSet then WriteLn('meThird is in');
if UsingConsts and mcThird <> 0 then WriteLn('mcThird is in');
end.
Запустите программу, и вы найдете TRUE
выставляется в каждом случае.
Итак ... только что перечислив и присвоив типы, я теперь покрываю слабо типизированный эквивалент. Импликация бит в конце состоит в том, что, если вы привыкли определять простые битмаски в моделях C, нет никаких оснований избегать использования правильных типов наборов в Delphi, поскольку они сводятся к одному и тому же. Таким образом, вы не теряете никакой эффективности, так как вы получаете сильную типизацию - «сильная типизация» в этом контексте означает, что вы не можете случайно назначить или проверить элемент, предназначенный для другого типа набора.
Можете вдаваться в подробности? Я предполагаю, что Крис сравнивал C-стиль побитовых AND и OR с целыми типами (например, стили окон или флаги создания процесса из Win32) с наборами Delphi. Но было бы лучше, если бы мы не догадались. Знаете ли вы, что такое сильная печать? Вы искали это с помощью веб-поиска? –
У нас нет страницы 65 книги Криса перед нами. Замечательно, что Крис здесь и может объяснить, но это ужасный вопрос в целом. Как насчет запроса о синтаксисе вместо ссылки на страницу? –