Originale-mail to me for new edition

 

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 Object interfaces.) They can hold dynamic arrays, and they can hold a special kind of static array called a variant array. (See Variant arrays.) 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.

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.

The standard function VarType returns a variant’s type code. The varTypeMask constant is a bit mask used to extract the code from VarType’s return value, so that, for example,

 

VarType(V) and varTypeMask = varDouble

 

returns True if V contains a Double or an array of Double. (The mask simply hides the first bit, which indicates whether the variant holds an array.) The TVarData record type defined in the System unit can be used to typecast variants and gain access to their internal representation. See the online Help on VarType for a list of codes, and note that new type codes may be added in future implementations of Object Pascal.

Variant type conversions

Variants in expressions

Variant arrays

Other variant types

 

Topic groups

 

See also

About types

Data types and variables: Overview

TVarData type

 

 

译文

 

变体类型

 

有时必需处理那些类型变化或不确定的数据,这时可以选用Variant类型的变量和参数。Variant类型表示的值在运行时可以改变数据类型。变体类型比常规类型具有更大的灵活性,但变体类型比静态范围类型占用较多的内存并且处理速度较慢。此外,对变体类型的非法操作通常运行时错误,而类似的错误对于常规类型则在编译时就能避免。还可以创建定制的变体类型。

默认情况下,变体可以保存除记录、集合、静态数组、文件、类、类引用、指针之外的任何类型的值。也就是说,变体可以保存除结构类型和指针之外的任何类型。变体可以保存接口以及接口中可以访问的方法和属性。(见对象接口。)变体可以保存动态数组,可以保存变体数组(variant array,静态数组的一种特殊类型)。(见变体数组。)在表达式和赋值语句中,变体可以与其他变体以及整数、实数、串、布尔值等混合,编译器会自动完成类型转换。

包含串的变体不能被索引。例如,如果V是一个保存了串值的变体,那么 V[1] 将导致运行时错误。

可以定义定制的变体来扩充变体类型,以保存任意值。例如,可以定义一个允许索引的变体串类型,或者保存关键的类引用、记录类型或静态数组类型等。定制的变体类型通过创建TCustomVariantType类的后裔来定义。

一个变体占用16字节的内存,由一个类型代码和一个值或值的指针(指针类型由类型代码决定)组成。所有变体在创建时都被初始化为一个特别的值Unassigned。特殊值Null表示未知或丢失的数据。

标准函数VarType返回变体的类型代码。varTypeMask常量是一个用于提取VarType返回值的代码的比特掩码。例如,对于表达式

 

VarType(V) and varTypeMask = varDouble

 

如果V包含了一个Double或一个Double数组,那么表达式返回True。(掩码只是隐藏了第一个比特位,该位表示变体是否保存了数组。)System单元中定义的TVarData记录类型可以用于对变体进行类型转换,以访问变体的内部表示。查看关于VarType的联机帮助,可以得到变体的类型代码列表。在未来的Object Pascal实现中,可能会增加新的类型代码。

 

变体类型转换

表达式中的变体

变体数组

其他变体类型(OleVariant

 

主题组

 

相关主题

关于类型

数据类型和变量:概述

TVarData类型

 

 

编者注

下面的代码举例说明了预定义常量Unassigned和标准函数Null的用法,以及标准函数VarIsNULLVarIsEmpty的用法。

对于如下声明

var

  V: Variant;

 

如下语句序列

  V := Unassigned;

  if V = NULL then

    ShowMessage('V = NULL');

将引发运行时错误;

 

如下语句序列

  V := NULL;

  if V = Unassigned then

    ShowMessage('V = Unassigned');

将引发运行时错误;

 

如下语句序列

  V := NULL;

  if V = NULL then ShowMessage('V = NULL');

将正确执行;

 

如下语句序列

  V := Unassigned;

  if VarIsNULL(V) then

    ShowMessage('V is NULL')

  else

    ShowMessage('V is not NULL');

将正确执行,此时VarIsNULL(V)返回False

 

如下语句序列

V := Unassigned;

if VarIsEmpty(V) then//函数返回True

  ShowMessage('V is empty')

  else

    ShowMessage('V is not empty');

  V := NULL;

  if VarIsEmpty(V) then//函数返回False

    ShowMessage('V is empty')

  else

ShowMessage('V is not empty');

将正确执行。