将打开的数组传递给匿名函数

时间:2014-11-11 10:47:15

标签: delphi delphi-xe2 anonymous-methods

什么是最不浪费的方式(即尽可能避免复制)将打开的字符串数组的内容传递给匿名函数,并从那里传递到另一个需要打开数组的函数?

问题是在Delphi XE2中的匿名函数中无法捕获打开的数组。

这说明了问题:

procedure TMyClass.DoSomething(const aStrings: array of string);
begin
  EnumItems(
    function (aItem: string) : Boolean
    begin
      Result := IndexText(aItem, aStrings) >= 0;
    end);
end;

编译器抱怨:"无法捕获符号' aStrings'"。

一个显而易见的解决方案是在动态数组中复制aStrings并捕获它。但我不想复制。 (虽然我的具体问题涉及一个字符串数组,并且由于引用计数,复制只会复制指针而不是字符串数据本身,因此学习如何解决任意大型非引用数组的问题也是有益的。计算类型。)

所以我尝试使用PString指向aStrings中的第一个字符串和长度的Integer值。但后来我无法找到将这些传递给InsertText的方法。

另一个约束:我希望可以调用DoSomething([a, b, c])

有没有一种方法可以在不制作数组副本的情况下完成此操作,而无需编写我自己的IndexText版本,而且不会显得难看?如果是这样,怎么样?

为了这个问题,我使用了IndexText,但找到一个函数的解决方案是有益的,这个函数不能轻易地重写以接受指针和长度参数而不是开放阵列。

这个问题的一个可接受的答案是:不,你不能这样做(至少不是没有复制或重写IndexText),尽管如此,我也想知道不是的根本原因。

2 个答案:

答案 0 :(得分:3)

如果您不想复制数组,则应更改DoSomething的签名以取代TArray<string>。如果你直接传递元素,你当然必须改变调用方(只有XE7才能以相同的方式传递动态数组) - 就像DoSomething([a, b, c])我的意思。

我的建议是不要乱用一些内部指针和内容,特别是不要用于开放数组。

答案 1 :(得分:2)

没有制作副本就没有办法做到这一点。无法捕获打开的数组,如果没有捕获,则无法将信息导入匿名方法。通常,您必须捕获,因为您需要延长变量的生命周期。

因此,您无法使用打开的数组执行此操作并避免复制。你可以改为:

  1. 从开放阵列切换到动态阵列TArray<string>
  2. 制作阵列的副本。您不会复制字符串数据,只是复制字符串的引用数组。