![](/img/trans.png)
[英]How to define an array type with items of different types and with a specific order in TypeScript?
[英]Can I define an array type of different types?
我想定义一个由不同类型组成的数组类型,例如String
、 Integer
、 Boolean
、 Double
等,但没有对象、结构或任何类似性质的东西。 然后我想将此类型用作 function 参数,例如...
type
TMyArray = array of ...?...;
function GetSomething(const Input: TMyArray): String;
var
X: Integer;
begin
for X:= 0 to Length(Input) - 1 do begin
//Identify type and handle accordingly...
//Serialize data for the result...
end;
end;
并像...一样使用它
Variable:= GetSomething(['some string', 123, 'something else', 12.3, false]);
那么,在遍历这样的数组时,如何识别每个元素是什么类型呢?
我很确定这是可能的,但甚至不知道要搜索什么术语。 我该怎么做呢?
我必须将其定义为变体数组吗? 或者有没有办法准确定义数组接受的类型?
编辑
不改变任何问题,但在 RRUZ 回答之后,我发现了一篇有趣的文章,介绍了以不同方式做这件事时的性能......
如果您的Delphi版本支持RTTI,您可以使用TValue
数组和Kind
属性。
{$APPTYPE CONSOLE}
uses
System.TypInfo,
System.Rtti,
System.SysUtils;
function GetSomething(const Input: array of TValue): String;
var
X: Integer;
LValue : TValue;
begin
for LValue in Input do begin
case LValue.Kind of
tkUnknown: Writeln('Unknown');
tkInteger: Writeln(Format('The Kind of the element is Integer and the value is %d',[LValue.AsInteger]));
tkChar: Writeln('Char');
tkEnumeration: if LValue.TypeInfo=TypeInfo(Boolean) then Writeln(Format('The Kind of the element is Boolean and the value is %s',[BoolToStr(LValue.AsBoolean, True)]));
tkFloat: Writeln(Format('The Kind of the element is Float and the value is %n',[LValue.AsExtended]));
tkString: Writeln('String');
tkSet: Writeln('Set');
tkClass: Writeln('Class');
tkMethod:Writeln('method');
tkWChar: Writeln('WChar');
tkLString: Writeln('String');
tkWString: Writeln('String');
tkVariant: Writeln('Variant');
tkArray: Writeln('Array');
tkRecord: Writeln('Record');
tkInterface: Writeln('Interface');
tkInt64: Writeln('Int64');
tkDynArray: Writeln('DynArray');
tkUString: Writeln(Format('The Kind of the element is String and the value is %s',[LValue.AsString]));
tkClassRef: Writeln('Class Ref');
tkPointer: Writeln('Pointer');
tkProcedure: Writeln('procedure');
end;
end;
end;
begin
try
GetSomething(['some string', 123, 'something else', 12.3, false]);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
另一种选择是使用array of const
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure GetSomething(const Input: array of const);
var
LIndex: Integer;
begin
for LIndex := Low(Input) to High(Input) do
begin
case Input[LIndex].VType of
vtWideString: Writeln('WideString = ''', WideString(Input[LIndex].VWideChar), '''');
vtInt64: Writeln('Int64 = ', Input[LIndex].VInt64^);
vtCurrency: Writeln('Currency = ', CurrToStr(Input[LIndex].VCurrency^));
vtInteger: Writeln('Integer = ', Input[LIndex].VInteger);
vtBoolean: Writeln('Boolean = ', BoolToStr(Input[LIndex].VBoolean, True));
vtChar: Writeln('Char = ''', Input[LIndex].VChar, '''');
vtExtended: Writeln('Extended = ', FloatToStr(Input[LIndex].VExtended^));
vtString: Writeln('ShortString = ''', Input[LIndex].VString^, '''');
vtPChar: Writeln('PChar = ''', Input[LIndex].VPChar, '''');
vtAnsiString: Writeln('AnsiString = ''', Ansistring(Input[LIndex].VAnsiString), '''');
vtWideChar: Writeln('WideChar = ''', Input[LIndex].VWideChar, '''');
vtPWideChar: Writeln('PWideChar = ''', Input[LIndex].VPWideChar, '''');
vtUnicodeString : Writeln('UnicodeString = ''', string(Input[LIndex].VUnicodeString), '''');
else
Writeln('Unsupported');
end;
end;
end;
begin
try
GetSomething(['some string', 123, 'something else', 12.3, false]);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
奇怪的是,没有人提到变体记录,这几十年来一直是Pascal的一个特征:
type
TVarRecType = (vrtInteger, vrtDouble {other types go here});
TVarRec = record
Field1: string; { can be omitted }
case RecType: TVarRecType of
vrtInteger:
IntValue: integer;
vrtDouble:
DblValue: double;
{ other cases go here }
end;
var
VarRec: TVarRecType;
begin
VarRec.Field1 := 'This is an example.';
VarRec.RecType := vrtInteger;
VarRec.IntValue := 4711;
{...}
VarRec.RecType := wrtDouble;
VarRec.DblValue := Pi;
{...}
end;
{ Oops, forgot the array part }
type
TVarRecArr = array[1..15] of TVarRec;
var
VarRecArr: TVarRecArr;
begin
VarRecArr[1].Field1 := 'This is the first record';
VarRecArr[1].RecType := wrtInteger;
VarRecArr[1].IntValue := 1;
{...}
end;
由于是用作参数,因此可以使用array of const
构造的array of const
。 也称为变量开放数组参数 。 更多关于我对这个问题的回答 。
它的工作方式与所需的不同类型数组相同。 关于该主题的Delphi docwiki文档
这真的很容易,而且Delphi的版本之间没有什么不同
首先,您需要记录名称和类型,例如:
Customer = record
OINTCUSTID : INTEGER ;
CUSTTYPE : SmallInt;
NAME : string[30];
end;
现在像这样改变你的数组:
Glb_CUSTOMER :ARRAY [1..20] OF Customer;
现在你有一个不同类型的数组。
假设最后您想将数组的 output 作为字符串获取(使用过程GetSomething )。 我认为您可以使用Variants
轻松做到这一点。
像这样定义你的数组:
MyArray = array of variant;
GetSomething procedure
现在很简单:
function TForm3.GetSomething(const Input: TMyArray): String;
var
X: Integer;
begin
for X:= 0 to Length(Input) - 1 do
//Identify type and handle accordingly...
//Serialize data for the result...
Result := Result + VarToStrDef(Input[X], '?') + ' | ';
end;
结果是预期的。
这一行:
Variable:= GetSomething(['some string', 123, 'something else', 12.3, false]);
返回这个结果:
一些字符串 | 123 | 别的东西 | 12,3 | 错误 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.