Передача массивов (динамических или статических) в методы/процедуры/функции с помощью open array parameters
, объявление может выглядеть так:
procedure WorkWithArray( const anArray : array of Integer);
(* or procedure WorkWithArray( var anArray : array of Integer); *)
var
i : Integer;
begin
for i := Low(anArray) to High(anArray) do
begin
// Do something with the "open array" anArray
WriteLn(anArray[i]);
end;
end;
...
var
staticArray : array[0..2] of Integer;
dynArray : array of integer;
dynArrayG : TArray<Integer>;
begin
SetLength(dynArray,10);
SetLength(dynArrayG,10);
WorkWithArray(staticArray); // Using a static array
WorkWithArray(dynArray); // Using a dynamic array
WorkWithArray(dynArrayG); // Using a dynamic generic array
...
end;
Передача таких массивов - это очень распространенная идиома, используемая во всем RTL Delphi, включая некоторые очень оптимизированные функции/процедуры для обработки массивов данных.
Предположим, что нам нужно вызвать WorkWithArray
с поддиапазоном наших массивов. Затем мы можем использовать внутреннюю Slice()
функцию.
Сначала без смещения, начиная с первого индекса:
Type
// Helper declarations
TIntLongArray = array[0..MaxInt div SizeOf(Integer) - 1] of integer;
PIntLongArray = ^TIntLongArray;
WorkWithArray(Slice(staticArray,2)); // No type cast needed for static arrays
WorkWithArray(Slice(PIntLongArray(@dynArray)^,2));
WorkWithArray(Slice(PIntLongArray(@dynArrayG)^,2));
Примечание: динамические массивы не вписываются непосредственно в функцию Slice()
, см. "Slice does not work with dynamic arrays"
. Поэтому необходимо использовать метод обхода пути с типом литья.
Что делать, если мы хотим работать с поддиапазоном, не начиная с первого элемента?
Возможна также:
WorkWithArray(Slice(PIntLongArray(@staticArray[1])^,2));
WorkWithArray(Slice(PIntLongArray(@dynArray[1])^,2));
WorkWithArray(Slice(PIntLongArray(@dynArrayG[1])^,2));
Примечание: сумма смещения и среза не должна превышать количество элементов массива.
Я знаю, что использование Копировать (myArray, x1, x2) можно использовать в случаях, когда ввод объявляется как const, но это сделает копию массива и неэффективно для больших массивов. (С риском также).
Наконец, мой вопрос:
Пока это демонстрирует способ передачи поддиапазона массива по ссылке с индексом начала и спецификатором длины, это выглядит немного неудобно. Есть ли лучшие альтернативы, и если да, то как?