Keywords Delphi

1 type Name = {packed} Record
Declarations ...
end;
2 type Name = {packed} record
Declarations ...
case {Tag :} Ordinal type of
Ordinal value {,Ordinal value...} : (Declarations);
{...}
end;


Description
The Record keyword is one of the most useful, and distinguishing features of Delphi (and the Pascal language). It provides a means of collecting together a set of different data types into one named structure.

Each field in the structure is referenced in the manner record.field.

When declared, the Packed option tells Delphi to minimise the storage taken by the record. This reduction in storage can impact performance, where data is not aligned to appropriate 2, 4 or 8 byte boundaries. The default is to align, with fillers where necessary.

There are two basic types of record field, as shown in the two syntax types:

1.Basic field declarations

These are standard Delphi variable declarations, such as :

size : Integer;

with the exception that their size must be defined. For example :

description : string[20];

because Delphi must know the precise amount of storage to allocate to that field in the record.

2.Case (Variant) field sections

These must always follow any basic field declarations (which is why the case statement does not have a terminating end; clause).

These allow different, alternative data types to overlay each other. For example, a patient record may have a different section of declarations for women compared to men. Using the same basic record with a Variant portion is sensible when the bulk of the record is common.

By default, fields in a record are aligned on Byte and Word boundaries as appropriate for performance reasons. For both Record types, the packed option allows this to be overriden to reduce storage requirements, with the necessary small performance penalty.

Notes
Using the With keyword, the fields of a record can be addressed without the need to prefix each with the record name.
Unlike Object Oriented languages like Java, the Delphi Record type provides a better performing mechanism for passing similar groups of data than data classes. They have their place in OO applications, especially where a class would otherwise have to be created for a structure of 2 or 3 fields.


Related commands
Case A mechanism for acting upon different values of an Ordinal
Packed Compacts complex data types into minimal storage
With A means of simplifying references to structured variables

Example code : Standard record definition
type
// Declare a customer record
TCustomer = Record
firstName : string[20];
lastName : string[20];
address1 : string[100];
address2 : string[100];
address3 : string[100];
city : string[20];
postCode : string[8];
end;
var
John, Sarah : TCustomer;
begin
// Set up the John's customer details
with John do
begin
firstName := 'John';
lastName := 'Smith';
address1 := '7 Park Drive';
address2 := 'Branston';
address3 := 'Grimworth';
city := 'Banmore';
postCode := 'BNM 1AB';
end;
// Set up John's sister similarly - simply copying the whole record
Sarah := John;
// And then changing the first name to suit
Sarah.firstName := 'Sarah';
// Now show the details of both customers
with John do ShowCustomer([firstName, lastName,
address1, address2, address3,city,
postCode]);
ShowMessage('');
with Sarah do ShowCustomer([firstName, lastName,
address1, address2, address3,city,
postCode]);
end;
// A procedure that displays a variable number of strings
procedure TForm1.ShowCustomer(const fields: array of string);
var
i : Integer;
begin
// Display all fields passed - note : arrays start at 0
for i := 0 to Length(fields)-1 do
ShowMessage(fields[i]);
end;

Show full unit code
John
Smith
7 Park Drive
Branston
Grimworth
Banmore
BNM 1AB

Sarah
Smith
7 Park Drive
Branston
Grimworth
Banmore
BNM 1AB



Example code : Record definition with a Case (Variant) tail section
type
// Declare a fruit record using case to choose the
// diameter of a round fruit, or length and height ohterwise.
TFruit = Record
name : string[20];
Case isRound : Boolean of // Choose how to map the next section
True :
(diameter : Single); // Maps to same storage as length
False :
(length : Single; // Maps to same storage as diameter
width : Single);
end;
var
apple, banana, fruit : TFruit;
begin
// Set up the apple as round, with appropriate dimensions
apple.name := 'Apple';
apple.isRound := True;
apple.diameter := 3.2;
// Set up the banana as long, with appropriate dimensions
banana.name := 'Banana';
banana.isRound := False;
banana.length := 7.65;
banana.width := 1.3;
// Show the attributes of the apple
fruit := apple;
if fruit.isRound
then ShowMessage(fruit.name +' diameter = '+
FloatToStrF(fruit.diameter, ffFixed, 2, 1)+'"')
else ShowMessage(fruit.name +' length = '+
FloatToStrF(fruit.length, ffFixed, 2, 1)+'" width = '+
FloatToStrF(fruit.width, ffFixed, 2, 1)+'"');
// Show the attributes of the banana
fruit := banana;
if fruit.isRound
then ShowMessage(fruit.name +' diameter = '+
FloatToStrF(fruit.diameter, ffFixed, 2, 1)+'"')
else ShowMessage(fruit.name +' length = '+
FloatToStrF(fruit.length, ffFixed, 2, 1)+'" width = '+
FloatToStrF(fruit.width, ffFixed, 2, 1)+'"');
end;

Show full unit code
Apple diameter = 3.2"
Banana length = 7.7" width = 1.3"