mảng Passing (động hoặc tĩnh) với các phương pháp/thủ tục/chức năng với open array parameters
, khai có thể trông như thế này:Đi qua lát một mảng tĩnh/động bằng cách tham chiếu với điểm bắt đầu và chiều dài specifier
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;
mảng Đi qua như thế này là một thành ngữ rất phổ biến được sử dụng trong suốt RTL Delphi, bao gồm một số hàm/thủ tục được tối ưu hóa để xử lý mảng dữ liệu.
Giả sử chúng ta cần gọi WorkWithArray
với một dãy ô của chúng tôi. Sau đó chúng ta có thể sử dụng hàm nội tại Slice()
.
đầu tiên mà không có một bù đắp, bắt đầu với chỉ số đầu tiên:
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));
Lưu ý: mảng động không phù hợp trực tiếp vào Slice()
chức năng, thấy "Slice does not work with dynamic arrays"
. Vì vậy, phương pháp workaround với đúc kiểu phải được sử dụng.
Điều gì sẽ xảy ra nếu chúng ta muốn làm việc với một phân đoạn không bắt đầu từ phần tử đầu tiên?
doable cũng như:
WorkWithArray(Slice(PIntLongArray(@staticArray[1])^,2));
WorkWithArray(Slice(PIntLongArray(@dynArray[1])^,2));
WorkWithArray(Slice(PIntLongArray(@dynArrayG[1])^,2));
Lưu ý: tổng các bù đắp và lát không được vượt quá số phần tử của mảng.
Tôi biết rằng việc sử dụng Sao chép (myArray, x1, x2) thể được sử dụng trong trường hợp các đầu vào được khai báo là const, nhưng điều này sẽ tạo một bản sao của mảng, và là ineffiecient cho mảng lớn. (Với nguy cơ tràn ngăn xếp là tốt).
Cuối cùng, câu hỏi của tôi:
Trong khi điều này chứng tỏ một cách để vượt qua một subrange của một mảng bằng cách tham khảo với một chỉ số bắt đầu và chiều dài specifier, có vẻ một chút vụng về. Có lựa chọn thay thế tốt hơn và nếu có thì làm cách nào?
Tại sao không đơn giản triển khai lại 'Slice' để chấp nhận mảng động? – user3764855
@ user3764855, 'Slice' là một hàm ma thuật (nội tại) được trình biên dịch chèn vào, chứ không phải là hàm bình thường để quá tải hoặc thay đổi theo từng phần. –
Bạn không thể trả lại con trỏ cho mảng thay vì sử dụng các phương thức nặc danh này. – user3764855