Vraag onbeperkt aantal parameters doorgeven aan procedure


in Delphi kan de procedure schrijven verwerken:

write(TF,st1)

en

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

Ik wil een procedure declareren die dat ook kan doen, wat is de syntaxis?

en de optie van:

write(TF,[st1,st2,st3])

is minder wenselijk, hoewel ik weet hoe dat moet.

het hoofddoel was om te slagen ShortStrings in functie, die een gelezen oproep uit bestand zou maken, en zou lezen in de lengte van de shortString zoals gedefinieerd. nochtans na het over te gaan als variant of in open opstelling de shortString verliest zijn "grootte" en wordt 255, waardoor het onbruikbaar wordt voor mij. maar het antwoord is nog steeds als je open array wilt doorgeven.


16
2017-07-24 13:33


oorsprong


antwoorden:


Allereerst Inc en Write zijn slechte voorbeelden omdat ze allebei een speciale behandeling krijgen van de compiler. Je kunt geen functie schrijven die zich precies zo gedraagt ​​als die twee zelf. Er zijn alternatieven die u moet onderzoeken.

Kijk eens naar overbelastingen

U kunt meerdere versies van uw methode maken met verschillende parameters en verschillende typen. Iets zoals dit:

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;

Dit is haalbaar als het vereiste aantal overbelastingen niet zo groot is. De compiler zou waarschijnlijk gemakkelijk veel overloads kunnen verwerken, maar je zou ze waarschijnlijk niet willen schrijven. Wanneer het aantal overbelasting een probleem wordt, kunt u overschakelen naar arrays:

Open Arrays gebruiken als parameters

Een functie kan een parameter van het type nemen array of YourType, en wanneer u die functie aanroept, kunt u zoveel parameters doorgeven als u nodig heeft:

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

En gebruik het dan als volgt:

MyInc(i, []); // no parameters
MyInc(i, [1]);
MyInc(i, [1, 34, 43, 12]);

25
2017-07-24 13:51



Gewoon om Cosmin's antwoord aan te vullen: als de lijst met parameters van verschillende types is, zou je een variante open array-parameter kunnen gebruiken (ook bekend als "array of const"). Meer informatie over Delphi-documentatie.

Voorbeeld (uit documentatie):

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
2017-07-24 16:37



Alleen voor ilustratieve doeleinden:

Delphi ondersteunt een manier om "echte" variabele-argumentenfuncties te schrijven, maar het is echt omslachtig en is vooral bedoeld voor het declareren van externe C-functies met variabele argumenten zoals printf, omdat het gaat om het spelen van vuile tricks op laag niveau om toegang te krijgen tot de argumenten in de stack.

Het gaat om het gebruik cdecl en varargs modifiers:

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;

Meer gedetailleerde uitleg is te vinden in het antwoord van Barry Kelly naar Hoe kan een functie met 'varargs' de inhoud van de stapel ophalen?


12
2017-07-24 16:00