gpt4 book ai didi

delphi - 字符串记录的 TDictionary 哈希被破坏

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

这重现了问题:

program Project1;

{$APPTYPE CONSOLE}

uses
Generics.Collections;
type
TStringRec = record
s1 : string;
s2 : string;
end;
TGetHash<TKey,TValue> = class(TEnumerable<TPair<TKey,TValue>>)
public
type
TItem = record
HashCode: Integer;
Key: TKey;
Value: TValue;
end;
TItemArray = array of TItem;
public
FItems: TItemArray;
end;
var
LCrossRef : TDictionary<TStringRec, integer>;
LRec : TStringRec;
i : integer;
begin
LCrossRef := TDictionary<TStringRec, integer>.Create();
LRec.s1 := 'test1';
LRec.s2 := 'test2';
LCrossRef.Add(LRec, 1);
LRec.s1 := 'test1';
LRec.s2 := 'test2';
if LCrossRef.TryGetValue(LRec, i) then begin
writeln('ok');
end else begin
LCrossRef.Add(LRec, 1);
for i := Low(TGetHash<TStringRec, integer>
(LCrossRef).FItems)
to High(TGetHash<TStringRec, integer>
(LCrossRef).FItems) do
WriteLn(TGetHash<TStringRec, integer>(LCrossRef).FItems[i].HashCode);
WriteLn('not ok');
end;
ReadLn;
end.

字典无法检索该项目并生成不同的 HashCode对于包含相同字符串的记录。

这在QC-#122791中有部分说明。但使用打包记录的解决方法不适用于字符串记录(至少当 TStringRec 声明为 packed record 时,上面的示例也会失败)。

对此有合理的解决方法吗?

我当前的策略是连接本来会进入记录的字符串并使用 TDictionary<string, TValue>相反,但这自然是不令人满意的。

最佳答案

这是一个已知的限制,是设计造成的。记录的默认比较器和哈希器仅适用于纯值类型记录以及没有填充的记录。

设计者可以选择使用 RTTI 来比较/散列记录。然而,他们选择不这样做。这种选择的一些明显合理的原因是:

  1. 他们不想强制不情愿的人使用 RTTI。
  2. 使用 RTTI 会对性能造成重大影响。

处理这个问题的方法是在使用通用集合时提供您自己的比较器和散列器。

您当前的连接字符串策略不起作用。考虑 'a''aa',然后是 'aa''a'。要使用基于文本的方法,您需要将记录序列化为 JSON。

关于delphi - 字符串记录的 TDictionary 哈希被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26160926/

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