Глава 10
ВАРИАНТЫ
10.1.
ОСНОВНЫЕ СВОЙСТВА ВАРИАНТА
Вариант (в Delphi 1 он отсутствует)
- это тип variant, разработанный специально для тех случаев, когда на этапе
компиляции программист не может сказать, какого типа данные будут использоваться
в выражении или как параметры вызова подпрограмм. Переменная-вариант занимает
в памяти дополнительные 2 байта, в которые помещается информация о действительном
типе переменной. Эта информация позволяет компилятору создать код, который будет
осуществлять необходимое преобразование типов на этапе прогона программы.
В переменную-вариант можно поместить:
-
целое или вещественное число;
-
логическое значение;
-
строку;
-
время и/или дату;
-
OLE-объект;
-
массив произвольной размерности
и длины, содержащий элементы одного из перечисленных выше типов.
Варианты могут участвовать в целочисленных,
вещественных, логических и время-дата выражениях при условии корректности соответствующих
преобразований. Например, если варианту v присвоена строка '1.0', то выражение
1+v будет правильным вещественным значением 2,0. Однако если v := 'текст', выражение
1+v вызовет исключение EVariantError.
В Delphi определены такие константы,
указывающие тип помещенных в вариант данных:
Таблица 10.1. Типы
возможных значений варианта
Имя
|
Константа
|
Смысл
|
varEmp.ty
|
$0000
|
Нет данных
|
varNull
|
$0001
|
Неизвестный тип параметра
|
varSmallInt
|
$0002
|
Целый тип Smallint
|
varlnteger
|
$0003
|
Целый тип Integer
|
varSingle
|
$0004
|
Вещественный тип Single
|
varDouble
|
$0005
|
Вещественный тип Double
|
varCurrency
|
$0006
|
Вещественный тип Currency
|
varDate
|
$0007
|
Тип дата-время
|
varOleStr
|
$0008
|
OLE-строка в кодировке Unicode
|
varDispatch
|
$0009
|
Указатель на OLE-объект
|
varError
|
$000А
|
Код ошибки
|
varBoolean
|
$000В
|
Тип WordBool
|
varVariant
|
$000С
|
Тип Variant (только для вариантных
массивов)
|
varUnknow
|
$0011
|
Неизвестный OLE-объект
|
varByte
|
$0100
|
Целый тип Byte
|
varString
|
$0100
|
Строковый тип
|
varArray
|
$2000
|
Вариантный массив
|
varByRef
|
$4000
|
Указатель на данные
|
Структура вариантного типа описывается
следующим образом:
TVarData =
packed record
VType: Word;
Reservedly Reserved2, ReservedS:
Word;
case
Integer of
varSmallInt: (VSmallInt: Smallint);
varlnteger: (VInteger: Integer);
varSingle: (VSingle: Single);
varDouble: (VDouble: Double);
varCurrency: (VCurrency: Currency);
varDate:(VDate: Double)
;
varOleStr: (VOleStr: PWideChar)
;
varDispatch: (VDispatch:
Pointer);
varError: (VError: WordBool);
varString: (VString: Pointer);
varArray: (VArray: PVarArray)
;
varByRef: (VPointer: Pointer);
end;
Как нетрудно убедиться, любая переменная
вариантного типа представляет собой 16-байтную запись, содержащую 8-байтную
вариантную часть, которая хранит либо собственно данные, либо их адрес (т. е.
указатель на динамически размещ
К чему приводится
|
Тип данных
в варианте
|
varEmpty
|
Целые
|
Вещественные
|
Дата-
Время
|
Строковые
|
Логические
|
К
дата-
'У:
время
|
30.12.
1899 00:00:00
|
Преобразование в
Double
|
Преобразование в
Double
|
Без
преобразования
|
Преобразование
в дату
|
Преобразование в Double
|
К целым
|
0
|
Преобразование в соответствующий
тип
|
Округление
до ближайшего целого
|
Округление до ближайшего
целого
|
Преобразование в целый
тип
|
0 для False,
иначе-1 (255 для
Byte)
|
.'К дата-
'У:
время
|
30.12.1899 00:00:00
|
Преобразование в
Double
|
Преобразование в
Double
|
Без преобразования
|
Преобразование в дату
|
Преобразование в
Double
|
К строковым
|
Пустая строка
|
Преобразование в символьный
вид
|
Преобразование в символьный
вид
|
Преобразование в символьный
вид
|
Без преобразования
|
'0'для False,'-!'
для True
|
К логическим
|
False
|
False для 0, иначе
True
|
False для 0, иначе
True
|
False для 0, иначе
True
|
False для 'False'
и для '0', иначе True
|
Без преобразования
|
енные данные). В поле VType в момент
создания варианта компилятор помещает, признак отсутствия данных varEmpty. В
работающей программе значение этого поля меняется в соответствии с текущим типом
данных, размещенных в вариантной части. Замечу, что программа не может получить
прямого доступа к полям вариантной записи. Получить тип вариантных данных можно
с помощью функции varType (см. ниже), а изменить тип - путем присваивания варианту
нового значения.