2012-11-07 135 views
0

它可以創建它接受可變數目的參數的函數:如何創建一個接受可變數量變量參數的函數?

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

'函數f(VAR X:const的數組):字符串;'如下所述:http://docwiki.embarcadero.com/RADStudio/XE3/en/Parameters_(Delphi)#Variant_Open_Array_Parameters –

+0

@DavidHeffernan但我不能像這樣調用它:f([a,b,c]),因爲它給了我一個錯誤:「常量對象不能作爲var參數傳遞」。那麼我怎麼稱呼這個功能呢? – Tom

+0

好吧,我錯了。你不能做你想做的。對不起 –

回答

2

湯姆將無法使用這個答案,因爲他的德爾福版本不夠高,但D2010或更高的人就能將擴展的rtti的TValue用於這種類型的挑戰。

下面是一個顯示一個小控制檯應用程序如何:

  • 創建一個從開放數組參數TValue的動態數組;
  • 將TValue的一個動態數組複製到一個新的動態數組中,在路上修改各個值;
  • 修改TValues「就地」動態數組中的項目。

享受。

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. 
+0

您正在創建原始數組的副本並修改該副本,而不是修改原始數組(AFAICT)。這些似乎是兩個單獨的事情。 –

+0

@KenWhite在ReturnNewArray我是,在ModifyArrayValues我不是。 –

+0

當然可以。你用'Source:= ValueArrayFromConstArray'創建數組(這不同於使用'ModifyArrayValues([varA,varB,varC])傳遞'數組的const'';然後傳遞** copy **(' Source')修改爲'ModifyArrayValues';這與修改原始數組並不一樣 –

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; 
+1

問題在於只適用於變體。 –

+0

這個問題是AllConst接受可變數量的參數,但不能改變它們,All()可以改變參數,但只接受其中的一個。 – Tom

+0

@大衛Heffermann,沒錯,從來沒有寫我自己的變種... http://www.uweraabe.de/Blog/2010/08/07/a-magical-gathering-part-2/ – bummi

相關問題