关于 array of const

本文深入探讨了Delphi中开放数组参数的应用,通过具体实例展示了如何使用arrayofconst处理不同类型的数据,并提供了简化函数的方法。此外,还讨论了不同类型数据在内存中的存储方式。
之前应该参考一下: 关于开放数组参数

//这是在 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;

转载于:https://www.cnblogs.com/del/archive/2008/04/17/1158858.html

### 关于 `Array.of` 的用法及其创建数组中特殊字符的处理 #### 1. **`Array.of` 的基本功能** `Array.of` 是一种用于创建数组的方法,它能够接收任意数量的参数并将这些参数转化为数组元素。这种方法相较于传统的字面量语法(如 `[...]`),更加灵活,尤其适用于动态参数列表的场景[^3]。 ```javascript const array = Array.of(1, 2, 3); console.log(array); // 输出 [1, 2, 3] ``` 此方法的一个显著特点是即使只有一个参数传入,也不会像 `new Array(size)` 那样将其视为长度设置,而是直接作为数组的第一个元素。 ```javascript const singleElementArray = Array.of(5); console.log(singleElementArray); // 输出 [5] const sizeBasedArray = new Array(5); console.log(sizeBasedArray); // 输出 [], 数组长度为5但无实际元素 ``` --- #### 2. **处理 `Array.of` 创建数组中的反斜杠** 当使用 `Array.of` 创建数组时,如果其中包含字符串形式的反斜杠或其他特殊字符,通常需要对其进行预处理后再构建数组。以下是几种常见的解决方案: ##### (1) **使用正则表达式替换反斜杠** 对于单个字符串或一组字符串,可以借助正则表达式将所有的反斜杠移除再传递给 `Array.of`。 ```javascript // 单一字符串示例 let strWithBackslash = "\\example\\string\\"; strWithBackslash = strWithBackslash.replace(/\\/g, ""); // 替换所有反斜杠 let resultArray = Array.of(strWithBackslash); console.log(resultArray); // 输出 ["examplestring"] // 多个字符串示例 let stringsWithBackslashes = ["\\first\\", "\\second\\"]; stringsWithBackslashes = stringsWithBackslashes.map(s => s.replace(/\\/g, "")); resultArray = Array.of(...stringsWithBackslashes); console.log(resultArray); // 输出 ["first", "second"] ``` 这里的关键是通过 `.replace(/\\/g, "")` 来全局匹配并删除字符串中的反斜杠[^1]。 --- ##### (2) **自定义过滤器移除特殊字符** 除了简单的反斜杠外,可能还需要针对更多种类的特殊字符进行清理。此时可设计一个通用的过滤机制,类似于 PHP 中 `$ArrFilters` 的概念[^2]。 ```javascript function removeSpecialChars(inputString, filterList) { let filteredString = inputString; for (let char of filterList) { const regex = new RegExp(char, "g"); filteredString = filteredString.replace(regex, ""); } return filteredString; } // 定义要过滤的字符集(ASCII 或 Unicode) const specialCharFilter = ["\\\\"]; // ASCII 转义序列表示反斜杠 // 测试数据 let rawString = "\\test\\with\\special\\chars\\"; rawString = removeSpecialChars(rawString, specialCharFilter); let finalArray = Array.of(rawString); console.log(finalArray); // 输出 ["testwithspecialchars"] ``` 在这个例子中,`removeSpecialChars` 函数允许用户指定一系列待移除的字符,并基于它们生成对应的正则表达式执行批量替换操作。 --- #### 3. **解决 JSON 解析过程中的转义问题** 有时,`Array.of` 接收的内容来源于外部输入(例如来自用户的 JSON 字符串)。这种情况下,原始数据可能存在额外的转义符号影响解析效果。对此需注意两点: - 在解码前先清除不必要的转义; - 利用内置工具如 `JSON.parse()` 正确解释合法的 JSON 文本。 ```javascript let jsonString = '{"key":"value","escaped":"\\content"}'; try { jsonString = jsonString.replace(/\\\\/g, "\\"); // 先初步简化双重转义 let parsedObject = JSON.parse(jsonString); // 提取值放入数组 let valuesAsArray = Array.of(parsedObject.key, parsedObject.escaped); console.log(valuesAsArray); // 输出 ["value", "content"] } catch (error) { console.error("Invalid JSON format:", error.message); } ``` 上述代码片段展示了如何在面对嵌套层次较深或者存在多重转义标记的数据时保持稳健性[^1]。 --- ### 总结 无论是单独处理还是批量清洗,都可以依靠现代 JavaScript 提供的强大字符串操纵能力来应对各种复杂的字符需求。结合 `Array.of` 的灵活性特点,开发者能够在不同业务场景下轻松构造满足条件的目标集合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值