delphi中array of const 借鉴

http://blog.163.com/zhangzhifeng688@126/blog/static/16526275820114995153163/

delphi中array of const 借鉴

2011-05-09 09:51:53| 分类: Delphi | 标签: |字号 订阅

在Delphi中关于Variant的用法示例(该文仅仅是备忘)

Delphi中关于 array of const 变体开放数组参数 .

变体开放数组参数


变体开发数组参数允许向单个过程或函数传递不同类型表达式的数组。要定义含有变体开放数组参数的例程,需要指定array of const作为参数类型。如,

procedure DoSomething(A: array of const);

这里声明了一个叫做DoSomething的过程,该过程可以操作不同种类的数组。

array of const结构等价于array of TVarRec。TVarRec,在单元System中声明,用于表示一个记录,记录中有一个可以保存多种值(整数、布尔、字符、实数、串、指针、类、类引用、接口、变体等)的变体部分。TVarRec中的VType字段表示数组中每个元素的类型。一些类型作为指针传递而不传递值;特别是长串,作为指针传递并且必需转换为string类型。

下面的例子在函数中使用了变体开放数组参数,该函数对接受的每个元素创建一个串表示法,最后连接成一个串。该函数中调用的串处理例程都定义在SysUtils单元中。

function MakeStr(const Args: array of const): string;
const
BoolChars: array[boolean] of char = ('F', 'T');
var
i: integer;
begin
result := '';
for i := 0 to High(Args) do
with Args[i] do
case VType of
vtInteger: result := result + IntToStr(VInteger);
vtBoolean: result := result + BoolChars[VBoolean];
vtChar: result := result + VChar;
vtExtended: result := result + FloatToStr(VExtended^);
vtString: result := result + VString^;
vtPChar: result := result + VPChar;
vtObject: result := result + VObject.ClassName;
vtClass: result := result + VClass.ClassName;
vtAnsiString: result := result + String(VAnsiString);
vtCurrency: result := result + string(VVariant^);
vtInt64: result := result + IntToStr(VInt64^);
end;
end;

caption := MakeStr(['test', 100, '', true, 3.14159, TForm]);

caption 显示如下:

test100T3.14159TForm

-----------------------------------------------------------------

为说明VInt64之类的,看下面:

特别说明: TVarData和 Variant 具有相同的内存布局!!也就是说,TVarData是对Variant的描述

Delphi syntax:

type
TVarArrayBound = packed record
ElementCount: Integer;
LowBound: Integer;
end;
TVarArrayBoundArray = array [0..0] of TVarArrayBound;
PVarArray = ^TVarArray;
TVarArray = packed record
DimCount: Word;
Flags: Word;
ElementSize: Integer;
LockCount: Integer;
Data: Pointer;
Bounds: TVarArrayBoundArray;
end;
TVarData = packed record

case Integer of
0: (VType: TVarType;
case Integer of
0: (Reserved1: Word;
case Integer of
0: (Reserved2, Reserved3: Word;
case Integer of
varSmallInt: (VSmallInt: SmallInt);
varInteger: (VInteger: Integer);
varSingle: (VSingle: Single);
varDouble: (VDouble: Double);

varCurrency: (VCurrency: Currency);
varDate: (VDate: TDateTime);
varOleStr: (VOleStr: PWideChar);
varDispatch: (VDispatch: Pointer);
varError: (VError: HRESULT);
varBoolean: (VBoolean: WordBool);
varUnknown: (VUnknown: Pointer);
varShortInt: (VShortInt: ShortInt);
varByte: (VByte: Byte);

varWord: (VWord: Word);
varLongWord: (VLongWord: LongWord);
varInt64: (VInt64: Int64);
varString: (VString: Pointer);
varAny: (VAny: Pointer);
varArray: (VArray: PVarArray);
varByRef: (VPointer: Pointer);
);
1: (VLongs: array[0..2] of LongInt);

);
2: (VWords: array [0..6] of Word);
3: (VBytes: array [0..13] of Byte);
);
1: (RawData: array [0..3] of LongInt);
end;

-------------------------------------------------------------------------

觉得复杂,看下面,它说的更清楚直接

----------------------------------------------------------------------

Delphi syntax:

type
PVarRec = ^TVarRec;
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended);
vtString: (VString: PShortString);
vtPointer: (VPointer: Pointer);
vtPChar: (VPChar: PChar);
vtObject: (VObject: TObject);
vtClass: (VClass: TClass);
vtWideChar: (VWideChar: WideChar);
vtPWideChar: (VPWideChar: PWideChar);
vtAnsiString: (VAnsiString: Pointer);
vtCurrency: (VCurrency: PCurrency);
vtVariant: (VVariant: PVariant);
vtInterface: (VInterface: Pointer);
vtWideString: (VWideString: Pointer);
vtInt64: (VInt64: PInt64);
end;

C++ syntax:

class TVarRec;

typedef TVarRec* PVarRec;
class TVarRec

{
public:
union
{
Integer VInteger;
Boolean VBoolean;
Char VChar;
PExtended VExtended;
PShortString VString;
Pointer VPointer;
PChar VPChar;
TObject* VObject;
TClass VClass;
WideChar VWideChar;
PWideChar VPWideChar;
Pointer VAnsiString;
PCurrency VCurrency;

PVariant VVariant;
};
union
{
Byte VType;
};
};

关于 array of const
2009-11-01 16:43
//这是在 System 单元定义的一组标识数据类型的常量:
vtInteger    = 0;
vtBoolean    = 1;
vtChar       = 2;
vtExtended   = 3;
vtString     = 4;
vtPointer    = 5;
vtPChar      = 6;
vtObject     = 7;
vtClass      = 8;
vtWideChar   = 9;
vtPWideChar  = 10;
vtAnsiString = 11;
vtCurrency   = 12;
vtVariant    = 13;
vtInterface  = 14;
vtWideString = 15;
vtInt64      = 16;

//这是定义在 System 单元关于数据类型的一个结构:
TVarRec = record
  case Byte of
    vtInteger:    (VInteger: Integer; VType: Byte);
    vtBoolean:    (VBoolean: Boolean);
    vtChar:       (VChar: Char);
    vtExtended:   (VExtended: PExtended);
    vtString:     (VString: PShortString);
    vtPointer:    (VPointer: Pointer);
    vtPChar:      (VPChar: PChar);
    vtObject:     (VObject: TObject);
    vtClass:      (VClass: TClass);
    vtWideChar:   (VWideChar: WideChar);
    vtPWideChar:  (VPWideChar: PWideChar);
    vtAnsiString: (VAnsiString: Pointer);
    vtCurrency:   (VCurrency: PCurrency);
    vtVariant:    (VVariant: PVariant);
    vtInterface:  (VInterface: Pointer);
    vtWideString: (VWideString: Pointer);
    vtInt64:      (VInt64: PInt64);
end;

作为参数的开放数组, 有时数组的成员类型是不确定的, 此时应该使用 array of const 定义; 详细举例:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{把不同数据类型返回字符串的函数}
function Fun1(arr: array of const): string;
var
  i: Integer;
begin
  Result := '';
  for i := Low(arr) to High(arr) do
  begin
    case arr[i].VType of
      vtInteger   : Result := Result + IntToStr(arr[i].VInteger)            + ' ';
      vtBoolean   : Result := Result + BoolToStr(arr[i].VBoolean, True)     + ' ';
      vtChar      : Result := Result + arr[i].VChar                         + ' ';
      vtExtended  : Result := Result + FloatToStr(arr[i].VExtended^)        + ' ';
      vtString    : Result := Result + PShortString(arr[i].VString)^        + ' ';
      vtPointer   : Result := Result + IntToStr(Integer(arr[i].VPointer))   + ' ';
      vtPChar     : Result := Result + arr[i].VPChar                        + ' ';
      vtObject    : Result := Result + arr[i].VObject.ClassName             + ' ';
      vtClass     : Result := Result + arr[i].VClass.ClassName              + ' ';
      vtWideChar  : Result := Result + arr[i].VWideChar                     + ' ';
      vtPWideChar : Result := Result + arr[i].VPWideChar                    + ' ';
      vtAnsiString: Result := Result + PAnsiChar(arr[i].VAnsiString)^       + ' ';
      vtCurrency  : Result := Result + CurrToStr(arr[i].VCurrency^)         + ' ';
      vtVariant   : Result := Result + string(arr[i].VVariant^)             + ' ';
      vtInterface : Result := Result + IntToStr(Integer(arr[i].VInterface)) + ' ';
      vtWideString: Result := Result + PWideChar(arr[i].VWideString)        + ' ';
      vtInt64     : Result := Result + IntToStr(arr[i].VInt64^)             + ' ';
    end;
  end;
end;

{简化上一个函数}
function Fun2(const arr: array of const): string;
var
  i: Integer;
const
  n = #32;
begin
  Result := '';
  for i := Low(arr) to High(arr) do with arr[i] do
  begin
    case VType of
      0 : Result := Result + IntToStr(VInteger)            + n;
      1 : Result := Result + BoolToStr(VBoolean, True)     + n;
      2 : Result := Result + VChar                         + n;
      3 : Result := Result + FloatToStr(VExtended^)        + n;
      4 : Result := Result + PShortString(VString)^        + n;
      5 : Result := Result + IntToStr(Integer(VPointer))   + n;
      6 : Result := Result + VPChar                        + n;
      7 : Result := Result + VObject.ClassName             + n;
      8 : Result := Result + VClass.ClassName              + n;
      9 : Result := Result + VWideChar                     + n;
      10: Result := Result + VPWideChar                    + n;
      11: Result := Result + PAnsiChar(VAnsiString)^       + n;
      12: Result := Result + CurrToStr(VCurrency^)         + n;
      13: Result := Result + string(VVariant^)             + n;
      14: Result := Result + IntToStr(Integer(VInterface)) + n;
      15: Result := Result + PWideChar(VWideString)        + n;
      16: Result := Result + IntToStr(VInt64^)             + n;
    end;
  end;
end;

{获取类型名的函数}
function Fun3(const arr: array of const): string;
var
  i: Integer;
const
  n = sLineBreak;
begin
  Result := '';
  for i := Low(arr) to High(arr) do with arr[i] do
  begin
    case VType of
      0 : Result := Result + 'Integer'   + n;
      1 : Result := Result + 'Boolean'   + n;
      2 : Result := Result + 'Char'      + n;
      3 : Result := Result + 'Extended'  + n;
      4 : Result := Result + 'String'    + n;
      5 : Result := Result + 'Pointer'   + n;
      6 : Result := Result + 'PChar'     + n;
      7 : Result := Result + 'Object'    + n;
      8 : Result := Result + 'Class'     + n;
      9 : Result := Result + 'WideChar'  + n;
      10: Result := Result + 'PWideChar' + n;
      11: Result := Result + 'AnsiString'+ n;
      12: Result := Result + 'Currency'  + n;
      13: Result := Result + 'Variant'   + n;
      14: Result := Result + 'Interface' + n;
      15: Result := Result + 'WideString'+ n;
      16: Result := Result + 'Int64'     + n;
    end;
  end;
end;

{测试}
procedure TForm1.Button1Click(Sender: TObject);
var
  a: Integer;
  b: Boolean;
  c: Char;
  d: Extended;
  e: ShortString;
  f: Pointer;
  g: PChar;
  h: TButton;
  i: TClass;
  j: WideChar;
  k: PWideChar;
  l: AnsiString;
  m: Currency;
  n: Variant;
  o: IInterface;
  p: WideString;
  q: Int64;
begin
  a := 1;
  b := True;
  c := 'a';
  d := 2;
  e := 'S';
  f := Pointer(3);
  g := 'P';
  h := TButton(Sender);
  i := TForm;
  j := #19975;
  k := '一';
  l := 'A';
  m := 4;
  n := 5;
  //o;
  p := '我的';
  q := 7;

  ShowMessage(Fun1([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q]));
  ShowMessage(Fun2([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q]));
  {结果如下:}
  {1 True a 2 S 3 P TButton TForm 万 一 A 4 5 0 我的 7 }

  ShowMessage(Fun3([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q]));
  {结果如下:
    Integer
    Boolean
    Char
    Extended
    String
    Pointer
    PChar
    Object
    Class
    WideChar
    PWideChar
    AnsiString
    Currency
    Variant
    Interface
    WideString
    Int64
  }
end;

{我试试没有在 TVarRec 中的类型是怎么归类的}
procedure TForm1.Button2Click(Sender: TObject);
var
  a: Byte;
  b: Word;
  c: Cardinal;
  d: Double;
  e: Real;
  f: TStrings;
begin
  ShowMessage(Fun3([a,b,c,d,e,f]));
  {结果如下:
    Integer
    Integer
    Integer
    Extended
    Extended
    Object
  }
end;

end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值