【问题标题】:How to pass array values as a procedure parameter?如何将数组值作为过程参数传递?
【发布时间】:2017-01-27 03:29:34
【问题描述】:

我假设我的问题可能已经存在于 SO 知识库中,但我只是找不到它。在这种情况下,请引导我到原点并投票关闭这个作为重复。 它是关于将数组参数传递给过程。

以下案例简单、直观且有效:

procedure MyProc(const A: array of ShortString);
begin
//
end

现在我可以调用MyProc 并直接将字符串传递给它:

MyProc(['no', 'trump', 'please']);

现在如果我声明一个 ShortString 类型的数组呢?

type
  TMyArray = array of ShortString;

procedure MyProc(const A: TMyArray);
begin
//
end

有没有办法直接执行MyProc传参数组类型? IE。使用与上述相同的过程调用。

+奖金问题:

type TMyRecord = record
  param, value: ShortString
end;

procedure MyProc(const R: TMyRecord);
begin
//
end

是否有任何技术可以调用过程并传递类型记录的值?类似(伪代码)

MyProc((TMyRecord.param='aaa', TMyRecord.value='bbb'));

我问的原因:我不想声明一个变量并设置它。相反,我想直接将数组/记录值作为过程参数传递。

【问题讨论】:

  • 开放数组参数和动态数组是有区别的,尽管它们的语法非常相似。 my article about this 中的更多内容。只有当您删除创建它们的函数时,才能以这种方式传递记录
  • 如果你需要调试它,你会希望你声明一个变量并设置它......
  • 一个问题也请一次。为什么要使用短字符串?
  • @David Heffernan,我使用 Delphi 10.1 Berlin,它有一个已知问题 (RSP-14914):如果您声明 array of string Code Insight 停止运行。对于这个特定示例,我使用了不停止显示的短字符串。
  • 走错了。现在您不支持 Unicode,性能会受到影响。不用担心代码洞察力。

标签: arrays delphi syntax parameter-passing


【解决方案1】:

是的,您所写的内容适用于 Delphi XE7 及更高版本。

program Project1;

{$APPTYPE CONSOLE}

type
  TMyArray = array of ShortString;

procedure MyProc(const A: TMyArray);
var
  s : ShortString;
begin
  for s in A do WriteLn(s);
end;

begin
  MyProc(['no', 'trump', 'please']);
  ReadLn;
end.

输出:

没有
王牌

XE7 引入了新的动态数组初始化语法,允许像上面那样调用函数。在此之前,您需要使用显式构造函数进行初始化,例如:

 MyProc(TMyArray.Create('no', 'trump', 'please'));

对于记录,你需要一个构造函数或其他方法来返回记录类型。这有效:

program Project1;

{$APPTYPE CONSOLE}

type
  TMyRecord = record
   param: ShortString;
   value: ShortString;
   constructor Create(AParam, AValue : ShortString);
  end;

constructor TMyRecord.Create(AParam: ShortString; AValue: ShortString);
begin
  param := AParam;
  value := AValue;
end;

procedure MyProc(const R: TMyRecord);
begin
  WriteLn(R.param);
  WriteLn(R.value);
end;

begin
  MyProc(TMyRecord.Create('foo', 'bar'));
  ReadLn;
end.

输出:


酒吧

【讨论】:

  • @smooty86 是的,当然。
  • 真的吗?我不知道它在最新的 Delphi 中是如何工作的,旧的不会接受它......可以将动态数组作为开放数组参数传递,而不是其他方式。
  • 我明白了。我使用的旧版本还不能以这种方式工作。
  • 还有一个替代方案。看我的回答。
  • 我说的是数组的事情。在旧版本中,无法将开放数组传递给动态数组参数。
【解决方案2】:

正如其他人所说,它可以在 Delphi XE7 及更高版本中完成。 在以前的版本中,数组类型不能直接作为参数传递。

如果你不能没有这种“舒适”。作为一个“丑陋”的解决方案,你可以使用一个中间函数,将动态数组复制到其相应的数组类型中:

function AsTypeArray(const MyArray : array of ShortString) : TMyArray;
begin
  SetLength(Result, Length(MyArray));
  Move(MyArray[Low(MyArray)], Result[0], Length(MyArray) * SizeOf(MyArray[Low(MyArray)]));
end;

所以你可以写:

MyProc(AsTypeArray(['no', 'trump', 'please']));

我不喜欢这个解决方案,但是如果你不能升级到 Delphi XE7 或更高版本并且你绝对想直接传递数组类型参数,我认为这是唯一的方法。

请注意,您可以将 TMyArray 对象作为参数传递给为接受动态数组而定义的函数:

procedure MyProc(const A: array of ShortString);
//...

var
  Arr : TMyArray;
begin
  //...
  MyProc(Arr); //It won't raise any error/warning
end;

对于记录,也需要一个返回记录类型的中间函数。

function MyRecord(Param : ShortString; Value : ShortString) : TMyRecord;
begin
  Result.Param := Param;
  Result.Value := Value;
end;

然后你就可以在不声明变量的情况下传递你的记录。

MyProc(MyRecord('aaa', 'bbb'));

在上一个 Delphi 的版本中,我认为没有其他方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多