向过程传递无限数量的参数

21

在Delphi中,过程write可以处理以下内容:

write(TF,st1)

并且。
write(TF,st1,st2,st3,st4);

我想声明一个过程,使它也能够做到这一点,语法是什么?
以及以下选项:
write(TF,[st1,st2,st3])

虽然我知道如何做到这一点,但不太理想。

主要目的是将 ShortString 传递到函数中,该函数将从文件中进行读取调用,并按定义的 shortString 长度进行读取。但是,在将其作为变体或开放数组传递后,shortString 失去了其“大小”,并变成了255,这使得此传递对于我来说无法使用。

但是,如果您想要传递开放数组,则仍然可以获得答案。


1
额... inc 不支持可变数量的参数。 - Andreas Rejbrand
1
@ROMANARMY,这确实回答了问题:如何创建一个过程write(TF,[st1,st2,st3]),而这不是问题的重点。 - none
嘿,没有人。你打算如何处理另一端的无限参数?Delphi缺乏C调用约定和处理可变参数(va_start、va_arg)的基本操作。 - Warren P
@Warren P,使用for循环进行从低到高的迭代。 - none
显示剩余3条评论
3个回答

31

只是为了补充Cosmin的回答:如果参数列表的类型不同,可以使用变体开放数组参数(也称为“const数组”)。

更多信息请参考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;

29

首先,IncWrite都不是好的示例,因为它们都会得到编译器的特殊处理。你无法自己编写一个与它们完全相同的函数。你应该探索一些替代方案。

看看重载

你可以使用不同数量和类型的参数创建多个版本的方法。类似这样:

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;

如果所需的重载数量不是很大,这是可行的。编译器可能会轻松处理许多重载,但您可能不想编写它们。当重载数量成为问题时,您可以切换到数组:

使用开放数组作为参数

一个函数可以接受类型为 YourType 数组 的参数,当您调用该函数时,您可以传递所需的任意数量的参数:

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

然后像这样使用它:

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

13
仅供举例说明:
Delphi支持一种编写“真实”的变量参数函数的方法,但它非常繁琐,并主要用于声明具有可变参数的外部C函数(如printf),因为它涉及使用一些低级别的技巧来访问堆栈中的参数。
它涉及使用和修饰符:
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'检索堆栈内容的函数问题的Barry Kelly回答中找到更详细的解释。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接