我是一个在克里斯的书中艰难跋涉的新手,有一个问题。
在第 65 页的最后一段提到使用正确的集合类型,因为它们提供了强类型。
有人可以解释这是什么意思,因为下面的示例看起来像我通常会做的事情,我正在尝试使用更好的做法。
我是一个在克里斯的书中艰难跋涉的新手,有一个问题。
在第 65 页的最后一段提到使用正确的集合类型,因为它们提供了强类型。
有人可以解释这是什么意思,因为下面的示例看起来像我通常会做的事情,我正在尝试使用更好的做法。
因为我不能侵犯我自己的版权,所以完整的部分:
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 中使用正确的集合类型,因为它们归结为相同的东西。因此,当您获得强类型时,您不会失去任何效率 - 在这种情况下,“强类型”本身意味着您不会意外分配或测试用于不同类型集合的元素。
您引用的代码是使用常量与枚举类型的比较,并证明这两种方法都可以正常工作。
const
mcFirst = 1;
...
对比
type
TMyEnum = (meFirst, ...
Chris 建议使用枚举类型而不是常量来利用强类型。