Delphi 如何创建一个接受可变数量变量参数的函数?
可以创建一个接受可变数量参数的函数:Delphi 如何创建一个接受可变数量变量参数的函数?,delphi,Delphi,可以创建一个接受可变数量参数的函数: function f(const x: array of const): String; 并以这种方式使用它: f([1,3,4, "hello"]); 也可以将参数定义为“可变”: 但是,有没有可能定义一个函数,它可以接受任意数量的whatver类型的参数并更改它们的所有值? 我知道我可以使用指针来实现这一点,但是我不知道传递的参数的类型,所以处理它们是非常不安全的 我只想创建一个函数,它可以返回许多不同类型的变量数量,而不仅仅是1个类型或1个变量。
function f(const x: array of const): String;
并以这种方式使用它:
f([1,3,4, "hello"]);
也可以将参数定义为“可变”:
但是,有没有可能定义一个函数,它可以接受任意数量的whatver类型的参数并更改它们的所有值?
我知道我可以使用指针来实现这一点,但是我不知道传递的参数的类型,所以处理它们是非常不安全的
我只想创建一个函数,它可以返回许多不同类型的变量数量,而不仅仅是1个类型或1个变量。我不想写无数行来使用这个函数——它应该是函数本身,在函数调用之前没有SetLength()或任何东西。这是迄今为止我做的最好的事情:
type TVarArr = Array of Variant;
PVarArr = ^TVarArr;
Procedure f(a: PVarArr);
var
i:Integer;
begin
SetLength(A^, 4);
a^[0] := 46;
end;
ar: TVarArr;
begin
f(@ar);
caption := IntToStr(ar[0]);
Tom将无法使用此答案,因为他的Delphi版本不够高,但D2010或更高版本的任何人都可以在此类挑战中很好地使用扩展rtti的TValue 以下是一个小型控制台应用程序,展示了如何:
- 从开放数组参数创建TValue的动态数组李>
- 将TValue的动态数组复制到一个新的动态数组中,同时修改各个值李>
- “就地”修改动态tValue数组中的项
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Rtti,
System.SysUtils,
System.TypInfo;
const
StringKinds: set of TTypeKind = [tkChar, tkString, tkWChar, tkLString, tkWString, tkUString];
type
TValueArray = array of TValue;
function ValueArrayFromConstArray(const aSource: array of TValue): TValueArray;
var
idx: Integer;
begin
SetLength(Result, Length(aSource));
for idx := Low(aSource) to High(aSource) do
Result[idx] := aSource[idx];
end;
function ReturnNewArray(const aSource: TValueArray): TValueArray;
var
idx: Integer;
begin
SetLength(Result, Length(aSource));
for idx := Low(aSource) to High(aSource) do
if aSource[idx].Kind in StringKinds then
Result[idx] := 'Dest' + aSource[idx].ToString
else
if aSource[idx].Kind in [tkInteger] then
Result[idx] := 10 + aSource[idx].AsInteger
else
Result[idx] := aSource[idx];
end;
procedure ModifyArrayValues(var aArray: TValueArray);
var
idx: Integer;
begin
for idx := Low(aArray) to High(aArray) do
if aArray[idx].Kind in StringKinds then
aArray[idx] := 'Dest' + aArray[idx].ToString
else
if aArray[idx].Kind in [tkInteger] then
aArray[idx] := 10 + aArray[idx].AsInteger
else
;//aArray[idx] := aArray[idx];
end;
var
Source: TValueArray;
Destination: TValueArray;
Item: TValue;
idx: Integer;
begin
Source := ValueArrayFromConstArray(['Some', 42, TObject]);
Destination := ReturnNewArray(Source);
idx := 0;
WriteLn('', #9, 'Old', #9, 'New');
WriteLn('-', #9, '----', #9, '----');
for Item in Source do
begin
WriteLn(idx, #9, Item.ToString, #9, Destination[idx].ToString);
Inc(idx);
end;
WriteLn;
WriteLn;
WriteLn('', #9, 'Modified');
WriteLn('-', #9, '----');
Source := ValueArrayFromConstArray(['first', 50, TValue.From<TFloatValue>(fvCurrency)]);
ModifyArrayValues(Source);
for Item in Source do
begin
WriteLn(idx, #9, Item.ToString);
end;
ReadLn;
end.
程序项目1;
{$APPTYPE控制台}
{$R*.res}
使用
系统,Rtti,,
System.SysUtils,
System.TypInfo;
常数
StringKinds:TTypeKind的集合=[tkChar、tkString、tkWChar、tkLString、tkWString、tkUString];
类型
TValue数组=TValue的数组;
函数值数组fromcontarray(constasource:TValue的数组):TValue数组;
变量
idx:整数;
开始
设置长度(结果,长度(源));
对于idx:=低(aSource)到高(aSource)do
结果[idx]:=aSource[idx];
结束;
函数ReturnNewArray(const aSource:TValueArray):TValueArray;
变量
idx:整数;
开始
设置长度(结果,长度(源));
对于idx:=低(aSource)到高(aSource)do
如果源[idx].Kind为StringKinds,则
结果[idx]:='Dest'+aSource[idx].ToString
其他的
如果是源[idx].Kind in[tkInteger],则
结果[idx]:=10+A源[idx].A集成器
其他的
结果[idx]:=aSource[idx];
结束;
过程修改数组值(var aArray:TValueArray);
变量
idx:整数;
开始
对于idx:=低(aArray)到高(aArray)do
如果aArray[idx].Kind是StringKinds,那么
aArray[idx]:='Dest'+aArray[idx].ToString
其他的
如果aArray[idx].Kind in[tkInteger]则
aArray[idx]:=10+aArray[idx]。AsInteger
其他的
;//aArray[idx]:=aArray[idx];
结束;
变量
资料来源:TValueArray;
目的地:TValueArray;
项目:价值;
idx:整数;
开始
Source:=valueArrayFromConstantArray(['Some',42,TObject]);
目标:=ReturnNewArray(源);
idx:=0;
书面语(“,#9,'旧',#9,'新');
书面语(“-”,#9,“----”,#9,'----);
对于源do中的项目
开始
WriteLn(idx,#9,Item.ToString,#9,Destination[idx].ToString);
公司(idx),;
结束;
书面语;
书面语;
书面语(“,#9,'修改”);
WriteLn('-',#9'-');
来源:=ValueArrayFromConstary(['first',50,TValue.From(fvCurrency)]);
修改阵列值(来源);
对于源do中的项目
开始
书面文件(idx,#9,第.ToString项);
结束;
ReadLn;
结束。
Tom将无法使用此答案,因为他的Delphi版本不够高,但D2010或更高版本的任何人都可以在此类挑战中充分利用扩展rtti的TValue
以下是一个小型控制台应用程序,展示了如何:
- 从开放数组参数创建TValue的动态数组李>
- 将TValue的动态数组复制到一个新的动态数组中,同时修改各个值李>
- “就地”修改动态tValue数组中的项
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Rtti,
System.SysUtils,
System.TypInfo;
const
StringKinds: set of TTypeKind = [tkChar, tkString, tkWChar, tkLString, tkWString, tkUString];
type
TValueArray = array of TValue;
function ValueArrayFromConstArray(const aSource: array of TValue): TValueArray;
var
idx: Integer;
begin
SetLength(Result, Length(aSource));
for idx := Low(aSource) to High(aSource) do
Result[idx] := aSource[idx];
end;
function ReturnNewArray(const aSource: TValueArray): TValueArray;
var
idx: Integer;
begin
SetLength(Result, Length(aSource));
for idx := Low(aSource) to High(aSource) do
if aSource[idx].Kind in StringKinds then
Result[idx] := 'Dest' + aSource[idx].ToString
else
if aSource[idx].Kind in [tkInteger] then
Result[idx] := 10 + aSource[idx].AsInteger
else
Result[idx] := aSource[idx];
end;
procedure ModifyArrayValues(var aArray: TValueArray);
var
idx: Integer;
begin
for idx := Low(aArray) to High(aArray) do
if aArray[idx].Kind in StringKinds then
aArray[idx] := 'Dest' + aArray[idx].ToString
else
if aArray[idx].Kind in [tkInteger] then
aArray[idx] := 10 + aArray[idx].AsInteger
else
;//aArray[idx] := aArray[idx];
end;
var
Source: TValueArray;
Destination: TValueArray;
Item: TValue;
idx: Integer;
begin
Source := ValueArrayFromConstArray(['Some', 42, TObject]);
Destination := ReturnNewArray(Source);
idx := 0;
WriteLn('', #9, 'Old', #9, 'New');
WriteLn('-', #9, '----', #9, '----');
for Item in Source do
begin
WriteLn(idx, #9, Item.ToString, #9, Destination[idx].ToString);
Inc(idx);
end;
WriteLn;
WriteLn;
WriteLn('', #9, 'Modified');
WriteLn('-', #9, '----');
Source := ValueArrayFromConstArray(['first', 50, TValue.From<TFloatValue>(fvCurrency)]);
ModifyArrayValues(Source);
for Item in Source do
begin
WriteLn(idx, #9, Item.ToString);
end;
ReadLn;
end.
程序项目1;
{$APPTYPE控制台}
{$R*.res}
使用
系统,Rtti,,
System.SysUtils,
System.TypInfo;
常数
StringKinds:TTypeKind的集合=[tkChar、tkString、tkWChar、tkLString、tkWString、tkUString];
类型
TValue数组=TValue的数组;
函数值数组fromcontarray(constasource:TValue的数组):TValue数组;
变量
idx:整数;
开始
设置长度(结果,长度(源));
对于idx:=低(aSource)到高(aSource)do
结果[idx]:=aSource[idx];
结束;
函数ReturnNewArray(const aSource:TValueArray):TValueArray;
变量
idx:整数;
开始
设置长度(结果,长度(源));
对于idx:=低(aSource)到高(aSource)do
如果源[idx].Kind为StringKinds,则
结果[idx]:='Dest'+aSource[idx].ToString
其他的
如果是源[idx].Kind in[tkInteger],则
结果[idx]:=10+A源[idx].A集成器
其他的
结果[idx]:=aSource[idx];
结束;
过程修改数组值(var aArray:TValueArray);
变量
idx:整数;
开始
对于idx:=低(aArray)到高(aArray)do
如果aArray[idx].Kind是StringKinds,那么
aArray[idx]:='Dest'+aArray[idx].ToString
其他的
如果aArray[idx].Kind in[tkInteger]则
aArray[idx]:=10+aArray[idx]。AsInteger
其他的
;//aArray[idx]:=aArray[idx];
结束;
变量
资料来源:TValueArray;
目的地:TValueArray;
项目:价值;
idx:整数;
开始
Source:=valueArrayFromConstantArray(['Some',42,TObject]);
目标:=ReturnNewArray(源);
idx:=0;
书面语(“,#9,'旧',#9,'新');
书面语(“-”,#9,“----”,#9,'----);
对于源do中的项目
开始
WriteLn(idx,#9,Item.ToString,#9,Destination[idx].ToString);
公司(idx),;
结束;
书面语;
书面语;
书面语(“,#9,'修改”);
WriteLn('-',#9'-');
来源:=ValueArrayFromConstary(['first',50,TValue.From(fvCurrency)]);
修改阵列值(来源);
对于源do中的项目
开始
书面文件(idx,#9,第.ToString项);
结束;
ReadLn;
结束。
函数f(变量x:常量数组):字符串代码>如此处所述:@DavidHeffernan B
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Rtti,
System.SysUtils,
System.TypInfo;
const
StringKinds: set of TTypeKind = [tkChar, tkString, tkWChar, tkLString, tkWString, tkUString];
type
TValueArray = array of TValue;
function ValueArrayFromConstArray(const aSource: array of TValue): TValueArray;
var
idx: Integer;
begin
SetLength(Result, Length(aSource));
for idx := Low(aSource) to High(aSource) do
Result[idx] := aSource[idx];
end;
function ReturnNewArray(const aSource: TValueArray): TValueArray;
var
idx: Integer;
begin
SetLength(Result, Length(aSource));
for idx := Low(aSource) to High(aSource) do
if aSource[idx].Kind in StringKinds then
Result[idx] := 'Dest' + aSource[idx].ToString
else
if aSource[idx].Kind in [tkInteger] then
Result[idx] := 10 + aSource[idx].AsInteger
else
Result[idx] := aSource[idx];
end;
procedure ModifyArrayValues(var aArray: TValueArray);
var
idx: Integer;
begin
for idx := Low(aArray) to High(aArray) do
if aArray[idx].Kind in StringKinds then
aArray[idx] := 'Dest' + aArray[idx].ToString
else
if aArray[idx].Kind in [tkInteger] then
aArray[idx] := 10 + aArray[idx].AsInteger
else
;//aArray[idx] := aArray[idx];
end;
var
Source: TValueArray;
Destination: TValueArray;
Item: TValue;
idx: Integer;
begin
Source := ValueArrayFromConstArray(['Some', 42, TObject]);
Destination := ReturnNewArray(Source);
idx := 0;
WriteLn('', #9, 'Old', #9, 'New');
WriteLn('-', #9, '----', #9, '----');
for Item in Source do
begin
WriteLn(idx, #9, Item.ToString, #9, Destination[idx].ToString);
Inc(idx);
end;
WriteLn;
WriteLn;
WriteLn('', #9, 'Modified');
WriteLn('-', #9, '----');
Source := ValueArrayFromConstArray(['first', 50, TValue.From<TFloatValue>(fvCurrency)]);
ModifyArrayValues(Source);
for Item in Source do
begin
WriteLn(idx, #9, Item.ToString);
end;
ReadLn;
end.