Неверный тип

Когда я пытаюсь преобразовать Array of Integer в TArray<Integer> в процедуре, я получаю сообщение об ошибке E2089 Invalid typecast. Как я могу ввести его так, чтобы он работал?

program Project11;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Math;

type
  TArrayManager<T> = record
    class procedure Shuffle(var A: TArray<T>); static;
  end;

class procedure TArrayManager<T>.Shuffle(var A: TArray<T>);
var
  I, J: Integer;
  Temp: T;
begin
  for I := High(A) downto 1 do
  begin
    J := RandomRange(0, I);
    Temp := A[I];
    A[I] := A[J];
    A[J] := Temp;
  end;
end;

procedure Test(var A: Array of Integer);
begin
  TArrayManager<Integer>.Shuffle(TArray<Integer>(A)); // Invalid typecast????
end;

var
  A: Array of Integer;
begin
  // TArrayManager<Integer>.Shuffle(TArray<Integer>(A)); // Works
  Test(A);

end.

person user3764855    schedule 08.07.2014    source источник


Ответы (2)


Вы не можете преобразовать параметр открытого массива в динамический массив. Они просто несовместимы. Если вы хотите работать с частью массива без копирования, боюсь, вам придется передавать массив и индексы отдельно. Как это:

procedure Foo(var A: TArray<Integer>; Index, Count: Integer);
begin
  // operate on A[Index] to A[Index+Count-1]
end;
person David Heffernan    schedule 08.07.2014

Тип «массив X» означает нечто иное как параметр, чем как переменная. Здесь это открытый массив, который на самом деле сильно отличается от динамического массива.

Если вы хотите передать динамический массив, вы должны указать тип параметра TArray<integer>.

person Mason Wheeler    schedule 08.07.2014
comment
К сожалению, я хотел бы передать его как параметр открытого массива, но не могу из-за того, что функция Slice этого не позволит. - person user3764855; 08.07.2014
comment
@ user3764855: Есть ли что-то, что Slice может сделать, чего не может Copy? - person Mason Wheeler; 08.07.2014
comment
Фактический параметр открытого массива может быть динамическим массивом, статическим массивом или даже специальным массивом при использовании конструктора открытого массива. Таким образом, вы не можете рассматривать его как динамический массив, потому что он может им и не быть. - person Rudy Velthuis; 08.07.2014
comment
@RudyVelthuis Вы не можете встроить метод с параметром открытого массива. Так что это большой недостаток. - person user3764855; 08.07.2014
comment
@MasonWheeler Copy скопирует весь массив. Slice будет использовать только его часть. @RudyVelthuis может знать об этом больше. - person user3764855; 08.07.2014
comment
@ user3764855: Я не совсем вижу проблему. В любом случае передавать его как параметр открытого массива было бы неправильно. Сделайте его TArray‹Integer› и все будет хорошо. - person Rudy Velthuis; 08.07.2014
comment
@RudyVelthuis Вы можете использовать TArray<Integer> с Slice? Когда это изменилось. - person user3764855; 08.07.2014
comment
@ user3764855: Copy(SomeArray) действительно скопирует весь массив. Copy(SomeArray, 0, SomeCount) не будет. - person Rudy Velthuis; 08.07.2014
comment
@RudyVelthuis Интересно. Таким образом, он действует точно так же, как Slice для низких значений. Почему бы тогда просто не Move ? - person user3764855; 08.07.2014
comment
@ user3764855: Нет, вы не можете использовать Slice. Однако вы можете использовать Copy. - person Rudy Velthuis; 08.07.2014
comment
@RudyVelthuis Это ссылка говорит, что Copy действительно сделает полную копию массива. Нельзя ли переопределить Slice для динамических массивов? - person user3764855; 08.07.2014
comment
В этом случае я определенно согласен с Мейсоном. Массив, который вы видите, является открытым массивом. В памяти он больше похож на статический массив, чем на динамический. - person Graymatter; 08.07.2014
comment
@user3764855: Я только что попробовал. Ссылка неверна. Copy(SomeDynArray, 0, SomeCount); работает как положено. Возможно, это было не всегда возможно в дни до XE, но в XE6 это работает. - person Rudy Velthuis; 09.07.2014
comment
А также в ХЕ. Не удалось попробовать с 2010, так как я не устанавливал его здесь. - person Rudy Velthuis; 09.07.2014
comment
@MasonWheeler Все, что может Slice, не может Copy. Сам смысл существования Slice заключается в том, что он не делает копии. - person David Heffernan; 09.07.2014
comment
@ Руди, я никогда не говорил, что Copy(SomeDynArray,0,SomeCount); не работает. Наоборот, работает, но имеет негативный эффект, что массив копируется, в этом и была суть моего вопроса. - person LU RD; 09.07.2014
comment
@Rudy Неверно предполагать, что стандартная функция с именем Copy не копируется. Не могли бы вы отказаться от этого ошибочного утверждения? - person David Heffernan; 09.07.2014
comment
@David: Где я это сказал? - person Rudy Velthuis; 10.07.2014
comment
Хммм... Я же сказал, что Copy скопирует весь массив, а Copy(A, B, C) нет. Это заявление вы имели в виду? Он, конечно, копирует, но не весь массив. - person Rudy Velthuis; 10.07.2014
comment
Да, я вижу, что неправильно истолковал то, что вы сказали. Извини. - person David Heffernan; 10.07.2014