передать в процедуру неограниченное количество параметров - PullRequest
16 голосов
/ 24 июля 2011

в Delphi процедура записи может обрабатывать:

write(TF,st1)

и

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

Я хочу объявить процедуру, которая также может делать это, каков синтаксис?

и вариант:

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

менее желателен, хотя я знаю, как это сделать.

главная цель состояла в том, чтобы передать ShortString s в функцию, чтосделать вызов чтения из файла, и будет читать с длиной shortString, как определено.однако после передачи его в качестве варианта или в открытом массиве shortString теряет свой «размер» и становится 255, что делает этот проход непригодным для меня.но ответ все равно получен, если вы хотите передать открытый массив.

Ответы [ 3 ]

27 голосов
/ 24 июля 2011

Просто для дополнения ответа Космина: если список параметров имеет разные типы, вы можете использовать вариант параметра открытого массива (также известный как «массив констант»). Подробнее о документации Delphi.

Пример (из документации ):

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 голосов
/ 24 июля 2011

Прежде всего Inc и Write - плохие примеры, потому что оба они получают специальную обработку от компилятора.Вы не можете написать функцию, которая ведет себя точно так же, как эти двое.Есть альтернативы, которые вы должны изучить.

Взгляните на перегрузки

Вы можете создать несколько версий вашего метода, используя различное количество параметров и разные типы.Примерно так:

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;

Это возможно, если необходимое количество перегрузок не так велико.Компилятор, вероятно, легко справится со многими перегрузками, но вы, вероятно, не захотите их писать.Когда количество перегрузок становится проблемой, вы можете переключиться на массивы:

Использование открытых массивов в качестве параметров

Функция может принимать параметр типа array of YourType, и когда вы вызываете эту функцию, выможет передать столько параметров, сколько вам нужно:

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

А затем использовать его следующим образом:

MyInc(i, []); // no parameters
MyInc(i, [1]);
MyInc(i, [1, 34, 43, 12]);
12 голосов
/ 24 июля 2011

Только для иллюстративных целей:

Delphi поддерживает способ написания "реальных" функций переменных аргументов, но он действительно громоздок и предназначен для использования в основном для объявления внешних функций C с переменными аргументами, такими как printf, так каквключает в себя некоторые грязные трюки низкого уровня для доступа к аргументам в стеке.

Это включает использование cdecl и 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;

Более подробное объяснение можно найти в ответе от Барри Келли до Как функция с 'varargs' может извлечь содержимое стека?

...