Program UsingVariantsl ; Var
V: Variant;{Описание вариантной переменной,
тип переменной не определен}
S: String;{Описание переменной типа String} Begin
V := 250; {Присвоение значения вариантной переменной V,
переменной назначается целочисленный тип данных;
V := 'It is a STRING' ;
{Присвоение значения вариантной переменной V, переменной назначается строковый тип данных}
S := V; {Строковой переменной присваивается строковое значение вариантной переменной}
End.
2.5.3. Определение типа вариантных переменных
Переменная типа Variant занимает в памяти шестнадцать байт, в которых находится информация о типе данных (код типа), хранящихся в данный момент в данной переменной и сами данные, либо указатель на них. Возможные коды типов данных для вариантных переменных, описанные в модуле System, представлены в табл. 2.4.
Для определения типа данных, хранимых в вариантной переменной, используется функция VarType,описанная в модуле Variants в следующем виде:
FunctionVarType(constV: Variant): TVarType;
Возвращаемое функцией VarType значение имеет тип аналогичный типу Word и содержит информацию о типе данных, а также о том, является ли значение, хранимое в переменной, массивом или указателем. Младшие двенадцать бит (три последние шестнадцатеричные цифры) этого значения содержат код типа, соответствующий константам, приведенным в табл. 2.4, а в старших четырех битах могут находиться следующие значения:
♦ нулевое значение $0000 — указывает на то, что данные заявленного типа хранятся непосредственно в вариантной переменной;
♦ значение $2000 (константа varArrayмодуля System) — указывает на то, что хранимые данные являются массивом элементов, имеющих тип, определяемый кодом типа данных;
♦ значение $4000 (константа varByRefмодуля System) — указывает на то, что хранимые данные являются ссылкой на соответствующий тип данных, определяемый кодом типа данных.
Для выделения части значения, содержащей код типа данных, предусмотрена константа varTypeMask (значение $0FFF), с помощью которой можно отделить код типа данных от дополнительных признаков:
<Переменная типа Variant> andvarTypeMask
В качестве примера использования описанных выше методов приведем фрагмент программы, формирующий строку S, содержащую подробную информацию о типе вариантной переменной V9.
S := 'Data element type: s;
Case VarType(V) and varTypeMask of
varEmpty: S := S + xThe variant is UnassignecT ;
varNuil: S := S + 'The variant is Null';
Таким образом, если в переменной v находится значение 2 0 0, то после выполнения данного фрагмента программы значением переменной s будет строка 'Data element type: A Byte', если переменной v задать значение 1221.66, то в переменной s будет строка 'Data element type:
Currency floating-point value (type Currency)'. Если же значение переменной V будет строковым, например, '1221.66', то значением переменной S будет такая строка: 'Data element type: Reference to a dynamically allocated string'.
2-5.4. Автоматическое приведение типов
Интересной особенностью вариантных переменных является то, что во время выполнения программы их тип автоматически приводится для соответствия смыслу выражения. Естественно, это правило верно не для всех типов вариантных переменных, а только для тех, в которых хранятся числовые (целочисленные и вещественные), строковые, символьные и логические значения.
Допустим, например, что в программе имеется вариантная переменная Vi, которой присвоено значение 2 0 0. После присвоения переменная vi будет целочисленной (иметь тип с кодом varByte):
Vi := 200;
Допустим также, что имеется переменная S типа string. Тогда в результате выполнения оператора присваивания s := vi, значением переменной s будет строка '200'. Таким образом, во время выполнения оператора значение целочисленной переменной будет автоматически переведено в строковый вид.
Более того, возможна и обратная ситуация, когда вариантная переменная строкового типа автоматически переводится в численную форму. Однако именно в таких ситуациях могут возникать ошибки времени выполнения. Рассмотрим пример безошибочного использования вариантной переменной (листинг 2.10).
Листинг 2.11. Пример t