在Delphi中将数组转换为const数组

时间:2018-05-29 13:45:00

标签: arrays delphi type-conversion delphi-10.2-tokyo

我正在寻找一种简单且理想的通用(或使用泛型)方式将array转换为array of const(= array of TVarRec)。我的具体情况是我有array of Variant并希望将其传递给Format()函数。

这是我到目前为止所发现的,但它看起来像我一样hackish:

function MyFormat(const Fmt: string; const Args: TArray<Variant>): string;
var
  A: array of TVarRec;
  I: Integer;
begin
  SetLength(A, Length(Args));
  for I:= Low(Args) to High(Args) do begin
    A[I].VType:= vtVariant;
    A[I].VVariant:= @Args[I];
  end;
  Result:= Format(Fmt, A);
end;

似乎有效。这样安全吗?

可以做得更短,更好,更快,还是可以使用现成的东西? :)

只是一些额外的想法和有趣的事实:

System.Rtti.TValue最近成了我的朋友。但是,它似乎缺少一个功能。我能够使用TValue.From()读取我的数组,但似乎没有办法将其作为array of TVarRec删除。有一个很棒的TValueArrayToArrayOfConst,但它并没有真正帮助,因为我必须首先构造一个array of TValue,这与存储在单个TValue中的数组不同。 。:(

至少TValue能够输出单个元素作为TVarRec,所以我想我可以为所有类型的数组创建一个通用的转换器。但...

你认为这有效吗?

for I:= Low(Args) to High(Args) do A[I]:= TValue.From(Args[I]).AsVarRec;

它编译,但TValue的内存在使用后被释放,并且由于TVarRec.VVariant是一个指针,它然后指向一个旧的位置,在下一个周期被覆盖。

2 个答案:

答案 0 :(得分:3)

您的功能安全快捷。它只分配一个小内存数组A[],并通过引用传递所有值。我无法更快地思考任何问题 - 而不是过早优化。我可能只会进行一些重构,以便将TArray<variant>重用到TArray<TVarRec>转换例程中。

如果您的输入确实是TValue.From().AsVarRec,那么使用TArray<Variant>肯定会更慢。

关于TVarRec dandling引用,你说得对:这些结构只是堆栈上的简单指针,没有分配,所以在函数调用期间所有引用的变量都应该可用。因此,如果您使用TArray<TVarRec>本地转换,则应确保在调用TArray<variant>函数时仍然分配format()

答案 1 :(得分:0)

简单明了的解决方案(以代码形式)。如果您的格式字符串(fmt)和值数组(sa)未知。

setlength(sa,5);      // or more
result := format(fmt,[sa[0],sa[1],sa[2],sa[3],sa[4]];