需要对Chris Rolliston XE2基金会中的按位运算符进行澄清

Tim*_* C. 1 delphi bitwise-operators

我是一个穿过克里斯的书跋涉的新手有一个问题.

在页65,最后一段提到使用适当的集类型,因为它们提供强类型.

有人可以解释这是什么意思,因为下面的例子看起来像我通常做的事情,我试图使用更好的做法.

Chr*_*ton 9

由于我不能影响我自己的版权,完整部分:

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.
Run Code Online (Sandbox Code Playgroud)

为此,faXXX定义常量,使第一个值为1,第二个值为2,第三个值为4,第四个值为8,依此类推.要将值添加到现有手册"set",使用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;
Run Code Online (Sandbox Code Playgroud)

通常,您应该尽可能使用正确的集合类型,因为它们提供了强大的类型和更高的可读性.尽管如此,下面的代码演示了这样一个事实,即在引擎盖下,"真实"套装和它们的手册,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.
Run Code Online (Sandbox Code Playgroud)

运行程序,你会发现TRUE在每种情况下输出.

所以...刚刚通过枚举和设置类型,我现在正在覆盖弱类型的等价物.最后一点的含义是,如果您习惯于以C方式定义简单的位掩码,那么没有理由避免在Delphi中使用正确的set类型,因为它们归结为同样的事情.因此,当您获得强类型时,您不会失去任何效率 - 在此上下文中"强类型"本身意味着您不会意外地分配或测试用于不同类型集合的元素.