Глава 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 (см. ниже), а изменить тип - путем присваивания варианту нового значения.