可以创建一个接受可变数量参数的函数:
function f(const x: array of const): String;
并以这种方式使用它:
f([1,3,4, "hello"]);
也可以将参数定义为“可更改”:
function g(var x: Byte): String;
var B: Byte;
g(B);
但是有可能定义一个函数,它可以接受任何类型的任何参数并改变它们的所有值吗? 我知道我可以使用指针执行此操作,但后来我不知道传递的参数的类型,因此弄乱它们是非常不安全的。
我只想创建一个函数,它可以返回许多不同类型的可变数量的变量,而不仅仅是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]);
答案 0 :(得分:2)
汤姆将无法使用这个答案,因为他的德尔福版本不够高,但D2010或更高版本的任何人都可以将扩展的rtti的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 :(得分:1)
Procedure All(var a:Array of Variant);
var
i:Integer;
begin
for I := Low(a) to High(a) do
begin
if VarType(a[i])=258 then
a[i] := a[i] + ' modified';
end;
end;
Procedure AllConst( a:Array of Variant);
var
i:Integer;
begin
for I := Low(a) to High(a) do
begin
Showmessage(a[i]);
end;
end;
procedure TForm3.Button1Click(Sender: TObject);
var
a:Array of Variant;
begin
AllConst([1,2,'Test']);
SetLength(a,3);
a[0] := 3.141;
a[1] := 'Test';
a[2] := 27;
all(a);
Showmessage(a[1]);
end;