4

良い一日、

TValueは Delphi-2010 以降の RTTI 機能です。

以前の質問に続いて、TValue を n 次元として返す再帰関数を作成しようとしました。行列(2D、3D、4D...)

たとえば、次の手順では n 次元のマトリックスが表示されます (n 次元のマトリックスのすべての要素が TValue 変数としてリストされます)。

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;

TValue から n 次元の行列を作成する関数を作成する方法がわかりません。たとえば、関数 CreateDynArray(Dimensions:array of integer; Kind:TTypeKind):TValue; が必要です。関数は、次のような次元を含む動的配列である TValue を返します。

Return=CreateDynArray([2,3],tkInteger); TValue を tkDynArray として返し、(Return) を表示する場合はリストします

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

アイデア

どうもありがとうございました。よい一日を!

4

1 に答える 1

5

動的配列を動的に作成するには、PTypeInfoに渡す型情報構造体 ( ) への参照が必要DynArraySetLengthです。nil ポインターへの参照を呼び出しDynArraySetLengthて渡すことで、新しい動的配列を作成できます。動的配列の特定の形状が Delphi プログラムにまだ存在しない場合PTypeInfo、コンパイラが生成する特定のポインタはありません。この場合、対応するPTypeInfoデータ構造を自分で生成する必要があります。面倒ですが、これは可能です。

率直に言って、スクリプト言語のような問題では、組み込みの Delphi 動的配列とは異なる構造を使用して配列を表現することをお勧めします。長い目で見れば、低レベルの RTTI データを動的に生成しようとするよりも、おそらくはるかに少ない作業になるでしょう。これは、Rtti ユニットでより高いレベルの抽象化が行われるようになったため、バージョンごとに変更される可能性が高くなります。

于 2010-12-31T00:16:49.713 に答える