• 关于 array of const


    之前应该参考一下: 关于开放数组参数

    //这是在 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.
    
    从这个例子中还能得到的启示是(根据网友的提示, 下面可能理解错了!):
    //不超过 4 字节的简单类型, 在内存中只有一个存放处.
    Integer;
    Boolean;
    Char;
    WideChar;
    
    //超过 4 字节的类型(包括字符串), 在内存中有两个存放处: 一个是指针位置; 一个是数据位置.
    Int64;
    Extended;
    Currency;
    Variant;
    ShortString;
    AnsiString;
    WideString;
    
    //指针: 只有 4 字节大小.
    Pointer;
    PChar(PAnsiChar);
    PWideChar;
    
    //对象: 复杂了...
    Object
    Class;
    IInterface;
    
  • 相关阅读:
    js去重的es6做法和es5做法
    对npm的认识
    pandas_分类与聚合
    pandas_使用透视表与交叉表查看业绩汇总数据
    pandas_使用属性接口实现高级功能
    pandas_一维数组与常用操作
    pandas_DateFrame的创建
    python 连接 mysql 的三种驱动
    Django学习路6_修改数据库为 mysql ,创建mysql及进行迁徙
    Django学习路5_更新和删除数据库表中元素
  • 原文地址:https://www.cnblogs.com/del/p/1158858.html
Copyright © 2020-2023  润新知