我正在寻找一种简单且理想的通用(或使用泛型)方式将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
是一个指针,它然后指向一个旧的位置,在下一个周期被覆盖。
答案 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]];