Ранее я демонстрировал, как удалять элементы из динамического массива:
В этой статье я начну со следующего кода:
type
TXArray = array of X;
procedure DeleteX(var A: TXArray; const Index: Cardinal);
var
ALength: Cardinal;
i: Cardinal;
begin
ALength := Length(A);
Assert(ALength > 0);
Assert(Index < ALength);
for i := Index + 1 to ALength - 1 do
A[i - 1] := A[i];
SetLength(A, ALength - 1);
end;
Вы не можете ошибиться с этим кодом. Используйте любое значение для X
, которое вы хотите; в вашем случае замените его на string
. Если вы хотите стать более любопытным и использовать Move
, то есть способ сделать это тоже.
procedure DeleteX(var A: TXArray; const Index: Cardinal);
var
ALength: Cardinal;
TailElements: Cardinal;
begin
ALength := Length(A);
Assert(ALength > 0);
Assert(Index < ALength);
Finalize(A[Index]);
TailElements := ALength - Index;
if TailElements > 0 then
Move(A[Index + 1], A[Index], SizeOf(X) * TailElements);
Initialize(A[ALength - 1]);
SetLength(A, ALength - 1);
end;
Поскольку X
равен string
, вызов Finalize
эквивалентен присвоению пустой строки этому элементу массива. Я использую Finalize
в этом коде, потому что он будет работать для всех типов элементов массива, даже типов, которые включают записи, интерфейсы, строки и другие массивы.
Для вставки вы просто перемещаете вещи в противоположном направлении:
procedure InsertX(var A: TXArray; const Index: Cardinal; const Value: X);
var
ALength: Cardinal;
TailElements: Cardinal;
begin
ALength := Length(A);
Assert(Index <= ALength);
SetLength(A, ALength + 1);
Finalize(A[ALength]);
TailElements := ALength - Index;
if TailElements > 0 then begin
Move(A[Index], A[Index + 1], SizeOf(X) * TailElements);
Initialize(A[Index]);
A[Index] := Value;
end;
Используйте Finalize
, когда вы собираетесь сделать что-то, выходящее за пределы языка, например, использовать небезопасную процедуру Move
для перезаписи переменной типа, управляемого компилятором. Используйте Initialize
при повторном вводе определенной части языка. (Язык определяет, что происходит, когда массив увеличивается или уменьшается с SetLength
, но не определяет, как копировать или удалять строки без использования оператора присваивания строки.)