记录类型
记录类型用于定义不同类型数据项的固定集合。记录中每个元素,或者说域,有它自己的类型。记录类型定义中列出了所有域,每个域对应一个域名,通过域名可以访问它。
下面简单列举了记录类型的定义、类型变量的声明以及这类变量的使用:
type Date = record Year: Integer; Month: Byte; Day: Byte; end; var BirthDay: Date; begin BirthDay.Year := 1997; BirthDay.Month := 2; BirthDay.Day := 14;
类和对象可以看作是记录类型的扩展。Delphi 库趋向于用类替代记录类型,不过Windows API中定义了许多记录类型。
记录类型中允许包含variant 域,它表示多个域能公用同一内存区,而且域可以是不同类型(这相应于C语言中的联合union)。换句话说,你可以通过variant 域或说是一组域访问记录中同一个内存位置,但是各个值仍需区别对待。variant类型主要用来存贮相似但又不同的数据,进行与类型映射(typecasting)相似的类型转换(自从typecasting 引入Pascal,已很少用到这种方法了)。虽然Delphi在一些特殊情况下还在用variant 记录类型,但是现在已经被面向对象技术或其他现代技术代替了。
variant 记录类型的应用不符合类型安全原则,因此不提倡在编程中使用,初学者更是如此。实际上,专家级的编程人员确实需要用到variant 记录类型,Delphi 库的核心部分就用到了这一类型。不管怎样,除非你是个Delphi 专家,否则你应避免使用variant记录类型。
以下为万一博客
//如果要记录一个人的姓名和年龄, 可以:
procedure TForm1.Button1Click(Sender: TObject);
var
name: string;
age: Word;
begin
{赋值}
name := '张三';
age := 18;
{读取}
ShowMessage(Format('%s今年%d岁', [name,age])); {张三今年18岁}
end;
//不如定义一个结构类型
procedure TForm1.Button2Click(Sender: TObject);
type
TPerson = record
name: string[12]; {在结构里面不能使用长字符串}
age: Word;
end;
var
person: TPerson; {声明结构变量}
const
str = '%s今年%d岁'; {为格式化输出准备一个常量}
begin
{赋值}
person.name := '李四';
person.age := 81;
{读取}
ShowMessage(Format(str, [person.name,person.age])); {李四今年81岁}
end;
------------------------------------------------------------------------------------------------------
压缩结构
type
TRec1 = record
i: Integer;
w: Word;
end;
TRec2 = packed record {压缩结构: 牺牲效率, 减小尺寸}
i: Integer;
w: Word;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(SizeOf(TRec1))); {8}
ShowMessage(IntToStr(SizeOf(TRec2))); {6}
end;
------------------------------------------------------------------------------------------------------
结构间的关系
TRec1 = record
name: string[ 12];
age: Word;
end;
TRec2 = record
name: string[ 12];
age: Word;
end;
var
RecA,RecB: TRec1;
RecX,RecY: TRec2;
procedure TForm1 .Button1Click(Sender: TObject);
begin
{给 RecA 赋值}
RecA .name := '张三';
RecA .age := 18;
{复制 RecA 给 RecB}
RecB := RecA;
{现在 RecB 的值和 RecA 一样}
ShowMessage(RecB .name); {张三}
{修改 RecB 的值}
RecB .name := '李四';
{RecA 的值不变, 因为现在 RecA、RecB 是两个不同的数据}
ShowMessage(RecA .name); {张三}
//RecX := RecA; {这样会出错!}
{尽管 RecX 与 RecA 的内部结构完全一样, 但 Delphi 认为它们是不同的数据类型}
RecX := TRec2(RecA); {但可以强制转换}
ShowMessage(RecX .name); {张三}
RecY .name := RecB .name; {交换内部值是可以的}
RecY .age := RecA .age;
ShowMessage(RecY .name); {李四}
end;