RTTI Delphi 创建一个 n 维矩阵作为 TValue
美好的一天,
TValue 是 Delphi-2010 及更高版本的 RTTI 功能。
继我的之前的问题之后,我尝试使循环函数返回n 维的 TValue。 矩阵(2D,3D,4D ...)
例如,
Procedure Show(X:TValue);
var i:integer;
begin
if x.IsArray then
begin
for i:=0 to x.GetArrayLength-1 do
show(x.GetArrayElement(i));
writeln;
end else
write(x.ToString,' ');
end;
,此过程将显示一个 n 维矩阵(它将列出 n 维矩阵中的所有元素作为 TValue 变量):我不明白如何创建函数从 TValue 创建 n 维矩阵。例如我需要一个 Function CreateDynArray(Dimensions:array of integer; Kind:TTypeKind):TValue;该函数将返回一个 TValue,它是一个动态数组,如何包含维度,例如:
Return=CreateDynArray([2,3],tkInteger);将返回 TValue 作为 tkDynArray 如果我显示(返回)将列出
0 0 0
0 0 0
不会终止。 我尝试从 TValue 创建一个具有 n 维的 DynArray
Procedure CreateArray(var Value:TValue; NewDimmension:integer; NewValue2Kind:TTypeKind; NewValue2:TValue; IsLast:Boolean);
var i:integer;
NewValue:TValue;
len:Longint;
begin
If Value.IsArray then// we have components in this dimension
begin
for i:=0 to Value.GetArrayLength-1 do// list all
begin
NewValue:=Value.GetArrayElement[i];
CreateArray(newValue,NewDimension,NewValue2Kind,NewValue2,IsLast);
Value.SetArrayElement(i,NewValue);
end;
end;
end else
begin
if isLast then
begin
len:=NewDimension;
DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len); //set length to NewDimension
for i:=0 to NewDimension-1 do //Fill all with 0
Value.SetArrayElement(i,NewValue2);
end else
begin
len:=NewDimension;
DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len);//I will create len TValues
end;
end;
var Index:array of integer;
Value:TValue;
ValuKind:TTypeKind;
......
......
....
Case token of
tokInt:
begin
ValueKind:=tkInteger;
Value:=0;
end;
.....
end;
Index:=GetIndexFromSintacticTree;//for example if i have int[20][30] index=[20,30]
for i:=0 to high(index) do
begin
if i = high(index) then CreateArray(Variable.Value,Index[i],ValueKind,Value,True)
else CreateArray(Variable.Value,Index[i],ValueKind,Value,False)
//Variable.Value is TValue
end;
//first TValue have 1 element, after that it will have 20 elements, and after that will have 20*30 elements
非常感谢,祝你有美好的一天!
Good day,
TValue is a Delphi-2010 and up RTTI feature.
Following on from my earlier question, I had tried to make recurrent function to return a TValue as a n-dimensional. matrix(2D, 3D, 4D...)
for example, this procedure will show a n-dimensional matrix(it will list all elements from a n-dimensional matrix as TValue variable):
Procedure Show(X:TValue);
var i:integer;
begin
if x.IsArray then
begin
for i:=0 to x.GetArrayLength-1 do
show(x.GetArrayElement(i));
writeln;
end else
write(x.ToString,' ');
end;
I don't understand how to create a function to create from a TValue an n-dimensional matrix. For example i need a Function CreateDynArray(Dimensions:array of integer; Kind:TTypeKind):TValue; and the function will return a TValue which is a dynamic array how contain the dimenssions for example:
Return=CreateDynArray([2,3],tkInteger); will return a TValue as tkDynArray
and if i will show(Return) will list
0 0 0
0 0 0
Is not terminated.
From a TValue i try to create a DynArray with n-dimensions
Procedure CreateArray(var Value:TValue; NewDimmension:integer; NewValue2Kind:TTypeKind; NewValue2:TValue; IsLast:Boolean);
var i:integer;
NewValue:TValue;
len:Longint;
begin
If Value.IsArray then// we have components in this dimension
begin
for i:=0 to Value.GetArrayLength-1 do// list all
begin
NewValue:=Value.GetArrayElement[i];
CreateArray(newValue,NewDimension,NewValue2Kind,NewValue2,IsLast);
Value.SetArrayElement(i,NewValue);
end;
end;
end else
begin
if isLast then
begin
len:=NewDimension;
DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len); //set length to NewDimension
for i:=0 to NewDimension-1 do //Fill all with 0
Value.SetArrayElement(i,NewValue2);
end else
begin
len:=NewDimension;
DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len);//I will create len TValues
end;
end;
var Index:array of integer;
Value:TValue;
ValuKind:TTypeKind;
......
......
....
Case token of
tokInt:
begin
ValueKind:=tkInteger;
Value:=0;
end;
.....
end;
Index:=GetIndexFromSintacticTree;//for example if i have int[20][30] index=[20,30]
for i:=0 to high(index) do
begin
if i = high(index) then CreateArray(Variable.Value,Index[i],ValueKind,Value,True)
else CreateArray(Variable.Value,Index[i],ValueKind,Value,False)
//Variable.Value is TValue
end;
//first TValue have 1 element, after that it will have 20 elements, and after that will have 20*30 elements
Thank you very much, and have a nice day!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要动态创建动态数组,您需要将其类型信息结构 (
PTypeInfo
) 的引用传递给DynArraySetLength
;调用 DynArraySetLength 并传递对 nil 指针的引用是创建新动态数组的方法。如果您的 Delphi 程序中尚不存在动态数组的特定形状,则编译器不会为您生成特定的PTypeInfo
指针。在这种情况下,您必须自己生成相应的PTypeInfo
数据结构。这是可能的,尽管很乏味。坦率地说,我建议您使用与内置 Delphi 动态数组不同的结构来表示类似脚本语言问题中的数组。从长远来看,它可能比尝试动态生成低级 RTTI 数据要少得多,因为它在 Rtti 单元中具有更高级别的抽象,因此更有可能从版本到版本进行更改。
To create a dynamic array dynamically, you need a reference to its type info structure (
PTypeInfo
) to pass toDynArraySetLength
; callingDynArraySetLength
and passing a reference to a nil pointer is how you can create a new dynamic array. If the specific shape of dynamic array does not already exist in your Delphi program, there will be no specificPTypeInfo
pointer that the compiler will generate for you. In this case, you would have to generate the correspondingPTypeInfo
data structure yourself. This is possible, though tedious.Frankly, I'd recommend you use a different structure than built-in Delphi dynamic arrays to represent arrays in your scripting language-like problem. In the long run it will probably be a lot less work than trying to dynamically generate the low-level RTTI data, which is more likely to change from version to version now that it has a much higher level abstraction in the Rtti unit.