gpt4 book ai didi

delphi - 带有子列表的通用记录 TList?

转载 作者:行者123 更新时间:2023-12-03 15:10:12 25 4
gpt4 key购买 nike

我想在 Delphi XE5 中使用带有子列表的通用记录 TList:

type
TMyRecord=record
Value1: Real;
SubList: TList<Integer>;
end;

TMyListOfRecords=TList<TMyRecord>;

var
MyListOfRecords: TMyListOfRecords;

不可能对记录字段进行赋值:

MyListOfRecords[0].Value1:=2.24; 

MyListOfRecords[0].SubList:=TList<Integer>.Create;

将导致编译器出现“左侧无法分配给”错误。

另请参阅:How to modify TList<record> value?

以下解决方法有效:

AMyRecord:=MyListOfRecords[0];
AMyRecord.Value1:=2.24;
AMyRecord.SubList:=TList<Integer>.Create;
AMyRecord.SubList.Add(33);
MyListOfRecords[0]:=AMyRecord;

由于性能问题,我想避免将数据复制到临时 AMyrecord。我宁愿直接访问记录字段和子列表。

处理这个问题的最佳方法是什么?

最佳答案

列表通过 List 公开其内部存储,这是一个动态数组。属性(property)。所以你可以写:

MyListOfRecords.List[0].Value1 := 2.24; 

与具有值(value)副本的替代方案相比,这是否会在性能上产生任何可测量的差异,我无法判断。值得检查一下。

正如@LURD正确所说,List返回内部存储。而这可能不止Count元素。具体来说有Capacity元素。因此,如果您使用它,则必须使用数组索引访问元素 0Count-1 。还要记住,对列表大小的修改可能涉及重新分配,因此内部存储可能会移动。您对List的任何引用仅在下次重新分配之前有效。

这些警告应该建议您只考虑使用 List如果性能限制需要的话。即便如此,也要谨慎使用。

在我的代码库中,我有 TList<T> 的替代方案谁的Items[]属性返回指向该元素的指针。容器仍然存储为动态数组,以实现高效的内存布局。与 List 相比,我更喜欢此选项属性(property),因为我觉得它可以带来更清晰的代码。

<小时/>

好的,您要求查看我的列表类,该列表类返回指向元素的指针。这是:

type
TReferenceList<T> = class(TBaseValueList<T>)
type
P = ^T;
private
function GetItem(Index: Integer): P;
public
property Items[Index: Integer]: P read GetItem; default;
public
// .... helper types for enumerators excised
public
function GetEnumerator: TEnumerator;
function Enumerator(Forwards: Boolean): TEnumeratorFactory;
function ReverseEnumerator: TEnumeratorFactory;
function IndexedEnumerator: TIndexedEnumeratorFactory;
end;

现在,需要一些解释。基类,TBaseValueList<T>是我对 TList<T> 的替代方案。您可以替换 TList<T>如果你希望。我没有,因为我的基类没有 Items属性(property)。因为我想要专门的类(class)来介绍它。我的其他专业是:

type
TValueList<T> = class(TBaseValueList<T>)
private
function GetItem(Index: Integer): T;
procedure SetItem(Index: Integer; const Value: T);
public
property Items[Index: Integer]: T read GetItem write SetItem; default;
end;

我的TBaseValueList<T>的实现是很明显的。它与 TList<T> 非常相似。我认为您真的不需要看到任何实现。这一切都非常明显。

作为获取元素引用的简单方法,您可以将 List 包装起来。像这样:

type
TMyList<T> = class(TList<T>)
public
type
P = ^T;
private
function GetRef(Index: Integer): P;
public
property Ref[Index: Integer]: P read GetRef;
end;

function TMyList<T>.GetRef(Index: Integer): P;
begin
Result := @List[Index];
end;

如果您想要比 Delphi 提供的更丰富的容器集,您可能会关注 Spring4D。虽然我不确定他们是否有像我的容器一样返回引用的东西。

关于delphi - 带有子列表的通用记录 TList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22212783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com