Quick start manual
Data types, variables, and constants
5-33
Variant types
The @ operator can also be used to assign an untyped pointer value to a procedural
variable. For example,
var StrComp: function(Str1, Str2: PChar): Integer;
ƒ
@StrComp := GetProcAddress(KernelHandle, 'lstrcmpi');
calls the GetProcAddress function and points StrComp to the result.
Any procedural variable can hold the value nil, which means that it points to
nothing. But attempting to call a nil-valued procedural variable is an error. To test
whether a procedural variable is assigned, use the standard function Assigned:
if Assigned(OnClick) then OnClick(X);
Variant types
Sometimes it is necessary to manipulate data whose type varies or cannot be
determined at compile time. In these cases, one option is to use variables and
parameters of type Variant, which represent values that can change type at runtime.
Variants offer greater flexibility but consume more memory than regular variables,
and operations on them are slower than on statically bound types. Moreover, illicit
operations on variants often result in runtime errors, where similar mistakes with
regular variables would have been caught at compile time. You can also create
custom variant types.
By default, Variants can hold values of any type except records, sets, static arrays,
files, classes, class references, and pointers. In other words, variants can hold
anything but structured types and pointers. They can hold interfaces, whose methods
and properties can be accessed through them. (See Chapter 10, “Object interfaces”.)
They can hold dynamic arrays, and they can hold a special kind of static array called
a variant array. (See “Variant arrays” on page 5-36.) Variants can mix with other
variants and with integer, real, string, and Boolean values in expressions and
assignments; the compiler automatically performs type conversions.
Variants that contain strings cannot be indexed. That is, if V is a variant that holds a
string value, the construction V[1] causes a runtime error.
You can define custom Variants that extend the Variant type to hold arbitrary values.
For example, you can define a Variant string type that allows indexing or that holds a
particular class reference, record type, or static array. Custom Variant types are
defined by creating descendants to the TCustomVariantType class.
Note
This, and almost all variant functionality, is implemented in the Variants unit.
A variant occupies 16 bytes of memory and consists of a type code and a value, or
pointer to a value, of the type specified by the code. All variants are initialized on
creation to the special value Unassigned. The special value Null indicates unknown or
missing data.