przekazać nieograniczoną liczbę parametrów do procedury

W Delphi procedura write może obsłużyć:

write(TF,st1)

I

write(TF,st1,st2,st3,st4);

Chcę zadeklarować procedurę, która może również to zrobić, jaka jest składnia?

Oraz opcja:

write(TF,[st1,st2,st3])
Jest mniej pożądane, chociaż wiem, jak to zrobić.

Głównym celem było przekazanie ShortString S do funkcji, która wywoła odczyt z pliku i odczyta na długości shortString zgodnie z definicją. jednak po przekazaniu go jako variant lub w otwartej tablicy shortString traci swój " rozmiar" i stać się 255, co czyni tę Przełęcz bezużyteczną, dla mnie. ale odpowiedź jest nadal dostępna, jeśli chcesz przekazać otwartą tablicę.

Author: fejese, 2011-07-24

3 answers

Po pierwsze Inc i Write są złymi przykładami, ponieważ oba są specjalnie traktowane przez kompilator. Nie możesz napisać funkcji, która zachowuje się dokładnie tak, jak ci dwaj robią to sami. Są alternatywy, które powinieneś zbadać.

Spójrz na przeciążenia

Możesz utworzyć wiele wersji swojej metody, używając różnej liczby parametrów i różnych typów. Coś takiego:

procedure MyInc(var i:Integer); overload;
procedyre MyInc(var i:Integer; const N:Integer); overload;
procedure MyInc(var i:Integer; const N1, N2: Integer); overload;
procedure MyInc(var i:Integer; const N1, N2, N3: Integer):overload;

Jest to możliwe, jeśli wymagana liczba przeciążeń nie jest tak duża. Kompilator prawdopodobnie poradzi sobie z wieloma przeciążeniami łatwo, ale prawdopodobnie nie będziesz chciał ich pisać. Gdy liczba przeciążeń staje się problemem, można przełączyć się na tablice:

Używanie otwartych tablic jako parametrów

Funkcja może przyjmować parametr typu array of YourType, a gdy wywołujesz tę funkcję, możesz przekazać tyle parametrów, ile potrzebujesz:

procedure MyInc(var i:Integer; Vals: array of Integer);

A następnie użyj go w ten sposób:

MyInc(i, []); // no parameters
MyInc(i, [1]);
MyInc(i, [1, 34, 43, 12]);
 25
Author: Cosmin Prund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-24 13:51:02

Aby uzupełnić odpowiedź Cosmina: jeśli Lista parametrów jest różnych typów, możesz użyć parametru Variant open array (znanego również jako "array of const"). więcej o dokumentacji Delphi.

Przykład (z Dokumentacja):

function MakeStr(const Args: array of const): string;
var
  I: Integer;
begin
  Result := '';
  for I := 0 to High(Args) do
     with Args[I] do
        case VType of
            vtInteger:  Result := Result + IntToStr(VInteger);
            vtBoolean:  Result := Result + BoolToStr(VBoolean);
            vtChar:     Result := Result + VChar;
            vtExtended: Result := Result + FloatToStr(VExtended^);
            vtString:   Result := Result + VString^;
            vtPChar:    Result := Result + VPChar;
            vtObject:   Result := Result + VObject.ClassName;
            vtClass:    Result := Result + VClass.ClassName;
            vtAnsiString:  Result := Result + string(VAnsiString);
            vtCurrency:    Result := Result + CurrToStr(VCurrency^);
            vtVariant:     Result := Result + string(VVariant^);
            vtInt64:       Result := Result + IntToStr(VInt64^);
  end;
end;
 26
Author: Fabricio Araujo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-30 16:16:33

Wyłącznie do celów ilustracyjnych:

Delphi wspiera sposób zapisu funkcji" prawdziwych " zmiennych argumentów, ale jest to bardzo uciążliwe i przeznaczone do użycia głównie do deklarowania zewnętrznych funkcji C ze zmiennymi argumentami, jak printf, ponieważ wiąże się to z wykonywaniem brudnych sztuczek niskiego poziomu, aby uzyskać dostęp do argumentów w stosie.

Polega na użyciu modyfikatorów cdecl i varargs:

procedure MyWrite_; cdecl;
begin
  ... some magic here ...
end;

var
  MyWrite: procedure; cdecl varargs = MyWrite_;

begin
  MyWrite(1);
  MyWrite(1, 2);
  MyWrite(1, 2, 3);
end;

Bardziej szczegółowe wyjaśnienie można znaleźć w odpowiedzi z Barry Kelly do Jak funkcja z 'varargs' może pobierać zawartość stosu?

 12
Author: JRL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:08:06