假设您没有在构造函数中指定比较器,TList.Create
您将获得TComparer<TSomeRecord>.Default
比较器。那是一个比较器,它使用CompareMem
.
这对于一个充满值类型的记录来说很好,没有填充。但否则,您将需要在实例化列表时提供自己的比较函数。
如果您想查看详细信息,记录的默认比较器在Generics.Defaults
. 对于较大的记录,相等比较器是这个函数:
function Equals_Binary(Inst: PSimpleInstance; const Left, Right): Boolean;
begin
Result := CompareMem(@Left, @Right, Inst^.Size);
end;
对于较小的记录,有一个优化,您的比较器将是 4 字节比较器。看起来像这样:
function Equals_I4(Inst: Pointer; const Left, Right: Integer): Boolean;
begin
Result := Left = Right;
end;
这有点奇怪,但它会将记录的 4 字节解释为 4 字节整数并执行整数相等比较。换句话说,与 相同CompareMem
,但效率更高。
您要使用的比较器可能如下所示:
TComparer<TSomeRecord>.Construct(
function const Left, Right: TSomeRecord): Integer
begin
Result := CompareStr(Left.Value, Right.Value);
end;
)
CompareText
如果您想要不区分大小写等,请使用。我使用了一个有序的比较函数,因为这就是我们TList<T>
想要的。
默认记录比较是相等比较这一事实告诉您,在不指定您自己的比较器的情况下尝试对记录列表进行排序将产生意想不到的结果。
鉴于默认比较器使用相等比较告诉您使用这样的比较器并非完全不合理:
TComparer<TSomeRecord>.Construct(
function const Left, Right: TSomeRecord): Integer
begin
Result := ord(not (Left = Right));
end;
)
这对于无序操作来说很好,IndexOf
但Contains
显然对于排序、二分搜索等毫无用处。