Как установить размер динамического массива в Oxygene (SetLength не работает) - PullRequest
1 голос
/ 09 ноября 2009

Что эквивалентно SetLength с использованием Oxygene? Я пытаюсь определить размер целочисленного массива.

var listIndexes: array of integer;
begin
     setLength(listIndexes,5);  // doesn't work
end;

Ответы [ 3 ]

2 голосов
/ 09 ноября 2009

Билл, функция Setlength не существует в Delphi-Prism (вы можете использовать пространство имен ShineOn.Rtl из ShineOn , которое имеет частичную реализацию функции Setlength).

В Delphi Prism вы можете попробовать это

type
IntegerArray = array of integer;

var listIndexes: IntegerArray;
listIndexes:=New IntegerArray(5);

или

 var listIndexes: Array of Integer;
 listIndexes:=New Integer[5];

UPDATE

Также вы можете написать свой собственный SetLength

method SetLength(var myArray: Array of Integer; NewSize: Integer);
var 
ActualLength: Integer;
begin
  var DummyArray: &Array := &Array.CreateInstance(typeOf(Integer), NewSize);
  if assigned(myArray) then
  begin
    ActualLength:= iif(myArray.Length > NewSize, NewSize, myArray.Length);
    &Array.Copy(myArray, DummyArray, ActualLength);
  end;
  myArray := array of integer(DummyArray);
end;
1 голос
/ 09 ноября 2009

[редактировать обновлено] Вы можете использовать метод Array.Resize , который, кажется, применяется только к приложениям .NET Framework 3.5. Эквивалентный код C # выглядит следующим образом:

    // Create and initialize a new string array.
    String[] myArr = {"The", "quick", "brown", "fox", "jumps", 
        "over", "the", "lazy", "dog"};

    // Display the values of the array.
    Console.WriteLine( 
        "The string array initially contains the following values:");
    PrintIndexAndValues(myArr);

    // Resize the array to a bigger size (five elements larger).
    Array.Resize(ref myArr, myArr.Length + 5); 

Однако, если вы ориентируетесь на более ранние версии .NET Framework или вам требуются очень частые изменения размера списка, я бы порекомендовал вам использовать .NET ArrayList или другую систему . Коллекции в .NET, которые могут значительно упростить ваш код и позволить вам использовать новые функции Framework, такие как Linq.

0 голосов
/ 15 июня 2019

Это просто быстрое обновление

RemObjects добавил классную новую инфраструктуру VCL, которую можно использовать как для .net, так и для их новых собственных целей. Это также влияет на строки.

Строки вне .net или VCL не являются изменяемыми . Вот почему их можно только уменьшить (String.Substring), что вы испытываете в своем вопросе.

Однако довольно легко создать собственный метод setlength (). Это не красиво и очень олдскул , но для немедленного решения, оно делает свою работу.

Я использую справочную таблицу, чтобы мы увеличивали строки в 16 раз. Напоминание (менее 16) также использует справочную таблицу. LLVM агрессивно оптимизирует подобный код. Это может быть ужасно, но это работает. Надеюсь это поможет. Просто переименуйте, как считаете нужным:

var str_growth_LUT: array[1..16] of String
= [' ',
   '  ',
   '   ',
   '    ',
   '     ',
   '      ',
   '       ',
   '        ',
   '         ',
   '          ',
   '           ',
   '            ',
   '             ',
   '              ',
   '               ',
   '                '];

class procedure QTXString.SetLength(var Text: String; NewLength: Integer);
begin
  var lCurrent := length(Text);
  if NewLength < lCurrent then
    Text := Text.Substring(1, NewLength)
  else  
    if NewLength > lCurrent then
    begin
      var diff := NewLength - lCurrent;
      var temp: String;

      // Calculate parts of 16
      var major := diff mod 16;
      var minor := diff - (major * 16);      

      // grow by chunks of 16
      while major > 0 do
      begin
        temp := temp + str_growth_LUT[16];
        dec(major);
      end;

      // Add reminder (less than 16)
      if minor > 0 then
        temp := temp + str_growth_LUT[minor];

      Text := temp;
    end;
end;
...