打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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
}


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
原创-VBA金税盘开票XML生成
泛型排序器 TComparer
php数组函数
delphi 取得任意程序的命令行
PHP的数据类型、类型转换及相关函数
我对DELPHI写的几个基类型
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服