RTTI Delphi Создать как TV значение n-мерной матрицы - PullRequest
4 голосов
/ 30 декабря 2010

Добрый день,

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;

Я не понимаю, как создать функцию для создания из телевизора n-мерной матрицы. Например мне нужна функция CreateDynArray (Размеры: массив целых чисел; Kind: TTypeKind): TValue; и функция вернет TValue, который является динамическим массивом, который содержит измерения, например:

Возврат = CreateDynArray ([2,3], tkInteger); вернет TValue как tkDynArray и если я покажу (возврат) будет список

0 0 0
0 0 0

Не прекращается. Из TValue я пытаюсь создать DynArray с n-измерениями

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

Большое спасибо и хорошего дня!

1 Ответ

5 голосов
/ 31 декабря 2010

Для динамического создания динамического массива вам необходима ссылка на его структуру типа информации (PTypeInfo) для передачи на DynArraySetLength;вызов DynArraySetLength и передача ссылки на нулевой указатель - вот как вы можете создать новый динамический массив.Если конкретная форма динамического массива еще не существует в вашей Delphi-программе, не будет специального указателя PTypeInfo, который сгенерирует для вас компилятор.В этом случае вам придется самостоятельно сгенерировать соответствующую PTypeInfo структуру данных.Это возможно, хотя и утомительно.

Честно говоря, я бы порекомендовал вам использовать структуру, отличную от встроенных динамических массивов Delphi, для представления массивов в задаче, связанной с языком сценариев.В долгосрочной перспективе это, вероятно, будет намного меньше работы, чем попытка динамического генерирования данных RTTI низкого уровня, которые с большей вероятностью будут меняться от версии к версии, поскольку теперь в модуле Rtti имеется гораздо более высокий уровень абстракции.

...