Глава 10
ВАРИАНТЫ
10.1. ОСНОВНЫЕ СВОЙСТВА ВАРИАНТА
Вариант (в Delphi 1 он отсутствует) - это тип variant, разработанный специально для тех случаев, когда на этапе компиляции программист не может сказать, какого типа данные будут использоваться в выражении или как параметры вызова подпрограмм. Переменная-вариант занимает в памяти дополнительные 2 байта, в которые помещается информация о действительном типе переменной. Эта информация позволяет компилятору создать код, который будет осуществлять необходимое преобразование типов на этапе прогона программы.
В переменную-вариант можно поместить:
Варианты могут участвовать в целочисленных, вещественных, логических и время-дата выражениях при условии корректности соответствующих преобразований. Например, если варианту 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 |
Без преобразования | Преобразование в дату |
К целым |
0 |
Преобразование в соответствующий тип |
Округление до ближайшего целого |
Округление до ближайшего целого |
Преобразование в целый тип |
.'К дата- 'У: время |
30.12.1899 00:00:00 |
Преобразование в Double |
Преобразование в Double |
Без преобразования |
Преобразование в дату |
К строковым |
Пустая строка |
Преобразование в символьный вид |
Преобразование в символьный вид |
Преобразование в символьный вид |
Без преобразования |
К логическим |
False |
False для 0, иначе True |
False для 0, иначе True |
False для 0, иначе True |
False для 'False' и для '0', иначе True |
енные данные). В поле VType в момент создания варианта компилятор помещает, признак отсутствия данных varEmpty. В работающей программе значение этого поля меняется в соответствии с текущим типом данных, размещенных в вариантной части. Замечу, что программа не может получить прямого доступа к полям вариантной записи. Получить тип вариантных данных можно с помощью функции varType (см. ниже), а изменить тип - путем присваивания варианту нового значения.