RTTI Delphi 创建一个 n 维矩阵作为 TValue

发布于 2024-10-09 10:16:14 字数 2669 浏览 6 评论 0原文

美好的一天,

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

The ideea

非常感谢,祝你有美好的一天!

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

The ideea

Thank you very much, and have a nice day!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别低头,皇冠会掉 2024-10-16 10:16:14

要动态创建动态数组,您需要将其类型信息结构 (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 to DynArraySetLength; calling DynArraySetLength 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 specific PTypeInfo pointer that the compiler will generate for you. In this case, you would have to generate the corresponding PTypeInfo 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文