@David trả lời rằng điều tra viên là bản sao của hồ sơ.
Ông cũng nói rằng việc bao bọc một mảng động bên trong một bản ghi sẽ cho phép một điều tra viên tùy chỉnh.
Dưới đây là một ví dụ về làm điều đó:
program ProjectCustomEnumerator;
{$APPTYPE CONSOLE}
type
PSomeRecord = ^TSomeRecord;
TSomeRecord = record
SomeField1 :string;
SomeField2 :string;
end;
TSomeRecordArray = record
private type
TSomeRecordDynArray = array of TSomeRecord;
// For x in .. enumerator
TSomeRecordArrayEnumerator = record
procedure Create(const AnArray : TSomeRecordDynArray);
private
FCurrent,FLast : Integer;
FArray : TSomeRecordDynArray;
function GetCurrent : PSomeRecord; inline;
public
function MoveNext : Boolean; inline;
property Current : PSomeRecord read GetCurrent;
end;
public
List : TSomeRecordDynArray;
// Enumerator interface
function GetEnumerator : TSomeRecordArrayEnumerator; inline;
end;
procedure TSomeRecordArray.TSomeRecordArrayEnumerator.Create(
const AnArray: TSomeRecordDynArray);
begin
FCurrent := -1;
FLast := Length(AnArray)-1;
FArray := AnArray;
end;
function TSomeRecordArray.TSomeRecordArrayEnumerator.GetCurrent: PSomeRecord;
begin
Result := @FArray[FCurrent];
end;
function TSomeRecordArray.TSomeRecordArrayEnumerator.MoveNext: Boolean;
begin
Inc(FCurrent);
Result := (FCurrent <= FLast);
end;
function TSomeRecordArray.GetEnumerator: TSomeRecordArrayEnumerator;
begin
Result.Create(Self.List);
end;
var
aList : TSomeRecordArray;
item : PSomeRecord;
i : Integer;
begin
// Fill array here
SetLength(aList.List,2);
aList.List[0].SomeField1 := 'Ix=0; Field1';
aList.List[0].SomeField2 := 'Ix=0; Field2';
aList.List[1].SomeField1 := 'Ix=1; Field1';
aList.List[1].SomeField2 := 'Ix=1; Field2';
i := -1;
for item in aList do
begin
// Item here a pointer to the item in the array
Inc(i);
WriteLn('aList index:',i,' Field1:',item^.SomeField1,' Field2:',item^.SomeField2);
end;
ReadLn;
end.
Sửa
Chỉ cần được hoàn chỉnh và theo dõi các ý kiến, đây là một ví dụ chứa chung cho bất kỳ mảng năng động của kỷ lục, với một tùy chỉnh điều tra viên.
program ProjectCustomEnumerator;
{$APPTYPE CONSOLE}
type
PSomeRecord = ^TSomeRecord;
TSomeRecord = record
SomeField1 :string;
SomeField2 :string;
end;
TRecordArray<T> = record
private type
TRecordDynArray = array of T;
// For x in .. enumerator
TRecordArrayEnumerator = record
procedure Initialize(const AnArray : TRecordDynArray);
private
FCurrent,FLast : Integer;
FArray : TRecordDynArray;
function GetCurrent : Pointer; inline;
public
function MoveNext : Boolean; inline;
property Current : Pointer read GetCurrent;
end;
public
List : TRecordDynArray;
// Enumerator interface
function GetEnumerator : TRecordArrayEnumerator; inline;
end;
procedure TRecordArray<T>.TRecordArrayEnumerator.Initialize(
const AnArray: TRecordDynArray);
begin
FCurrent := -1;
FLast := Length(AnArray)-1;
FArray := AnArray;
end;
function TRecordArray<T>.TRecordArrayEnumerator.GetCurrent: Pointer;
begin
Result := @FArray[FCurrent];
end;
function TRecordArray<T>.TRecordArrayEnumerator.MoveNext: Boolean;
begin
Inc(FCurrent);
Result := (FCurrent <= FLast);
end;
function TRecordArray<T>.GetEnumerator: TRecordArrayEnumerator;
begin
Result.Initialize(Self.List);
end;
var
aList : TRecordArray<TSomeRecord>;
item : PSomeRecord;
i : Integer;
begin
// Fill array here
SetLength(aList.List,2);
aList.List[0].SomeField1 := 'Ix=0; Field1';
aList.List[0].SomeField2 := 'Ix=0; Field2';
aList.List[1].SomeField1 := 'Ix=1; Field1';
aList.List[1].SomeField2 := 'Ix=1; Field2';
i := -1;
for item in aList do
begin
// Item here a pointer to the item in the array
Inc(i);
WriteLn('aList index:',i,' Field1:',item^.SomeField1,' Field2:',item^.SomeField2);
end;
ReadLn;
end.
Nguồn
2013-09-02 21:02:42
Tôi sẽ triển khai con trỏ bản ghi cho mọi trường hợp tương tự. Bất cứ lúc nào bạn muốn truyền các bản ghi xung quanh và sửa đổi nội dung của chúng ở những nơi khác nhau, một con trỏ bản ghi 'PSomeRecord' hoạt động hiệu quả hơn rất nhiều và bạn không phải lo lắng về việc nó được sao chép. Đặc biệt là nếu nó chứa rất nhiều nội dung (rất nhiều bộ nhớ). –
@Jerry Nhưng bây giờ bạn phải quản lý suốt đời –
@ David True, đó là một thay đổi lớn trong cách mọi thứ hoạt động, nhưng như tôi đã nói, nếu một bản ghi duy nhất tiêu thụ một lượng lớn bộ nhớ, tốt nhất là giữ chúng trong con trỏ. –