Arrays Delphi中数组到常量数组的转换

Arrays Delphi中数组到常量数组的转换,arrays,delphi,type-conversion,delphi-10.2-tokyo,Arrays,Delphi,Type Conversion,Delphi 10.2 Tokyo,我正在寻找一种简单且理想的通用方法,或者使用泛型方法将数组转换为const=TVarRec数组。我的具体情况是,我有一个Variant数组,并希望将其传递给Format函数 这是我到目前为止所发现的,但在我看来,它看起来很粗糙: function MyFormat(const Fmt: string; const Args: TArray<Variant>): string; var A: array of TVarRec; I: Integer; begin SetLe

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

这是我到目前为止所发现的,但在我看来,它看起来很粗糙:

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;

它可以编译,但TValue的内存在使用后会被释放,而且由于TVarRec.VVariant是一个指针,因此它会指向某个旧位置,该位置在下一个循环中会被覆盖。

您的函数既安全又快速。它只分配一个小内存数组a[],并通过引用传递所有值。我无法更快地思考任何事情——如果不进行过早的优化。我可能只会进行一些重构,以将TArray重用到TArray转换例程中

如果您的输入确实是TArray,那么使用TValue.From.AsVarRec肯定会慢一些


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

这是一个简单的代码解决方案。如果您的formatstring fmt和值数组sa未知

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

TVarRec就是这样工作的:只是一个指向现有内容的指针。因此,您需要在子函数调用期间分配变量。是的,这是安全的。没有比这更简单的方法了,阿福。有关TVarRec如何工作的解释,请参阅和阅读。你的代码之所以有效,是因为TVarRec确实通过指针传递了一个变量。我投票结束这个问题,因为更安全、更短、更快不适合你SO@DavidHeffernan,上次我问了一个问题,并把我的答案变成了一个答案,希望得到其他/更好的答案。你不喜欢它。现在我没有回答我自己的问题,而是把我发现的一切都直接放到了问题中。你还是不喜欢。所以你说最好只是问问题,而不提我到目前为止发现了什么?我猜你的下一个问题是我没有提供足够的背景资料。这一切对我来说毫无意义。我该如何提问才能让你接受?问题在标题中,如果您在它前面加上如何。是的,我正好有一个Variant数组,希望将它传递给Format函数。然而,一个通用/通用的解决方案,比如TValue是否支持它,会更好。我不喜欢为了将一个数组转换成另一个数组而编写这么多代码,即使较短的解决方案速度较慢。如果您想减少键入,正如我建议的那样,进行一些重构,将TArray转换例程作为一个独立的函数重用到TArray转换例程中。TValue显然超出了范围,因为您已经将变量值用作容器。这不是一种通用的方法,因为它只适用于长度为5的数组。是和否。如果您知道formatstring从不使用超过N个参数,则可以在示例中将长度设置为n5。格式只使用所需的参数。如有必要,可以在以后重置数组的长度。也许不是皇家的方式,但你也要求一个简单的方式。
setlength(sa,5);      // or more
result := format(fmt,[sa[0],sa[1],sa[2],sa[3],sa[4]];