人们可以推荐快速简单的方法来组合两个对象的哈希码.我并不太担心碰撞,因为我有一个Hash Table可以有效地处理这个问题我只想要尽可能快地生成代码的东西.
阅读SO和网络似乎有几个主要候选人:
人们会推荐什么?为什么?
我有一个将动态数组TData = TArray<Byte>作为参数的过程.
procedure DoStuff(const Input: TData);
begin
  // do nothing
end;
还有一个返回动态数组的函数.
function SomeData: TData;
begin
  Result := [1, 2];
end;
当我使用下面示例中的过程时,DoStuff获取以下数据(1,2,3,1,3),但在DoStuff完成后我得到一个EInvalidPointer异常.
procedure TForm1.Button1Click(Sender: TObject);
begin    
  DoStuff([1, 2, 3] + SomeData);
end;
调用DoStuff([1, 2] + SomeData);不会导致错误,当数组大于4项时,它似乎变得敏感.如果我使用临时变量来保存数组,DoStuff仍会得到(1,2,3,1,2),但没有错误.
procedure TForm1.Button2Click(Sender: TObject);
var
  Temp: TData;
begin
  Temp := [1, 2, 3] + SomeData;
  DoStuff(Temp);
end;
看起来像指针异常与其中一个动态数组超出范围时的释放有关.
我不应该以这种方式使用动态数组吗?工作时,这非常干净地解决了我当前的问题.
我也试过使用array of Byte;而不是TArray<Byte>;但有相同的结果.
完整的测试单位:
unit Main;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, …鉴于以下内容:
LBytes: TBytes;
LArr: array[1..512] of Byte;
...
SetLength(LBytes, 512);
什么是正确的Move()调用将所有字节从LBytes复制到LArr?
Move(LBytes[0], LArr, Length(LBytes)); // works
Move(LBytes[0], LArr[1], Length(LBytes)); // works, too
Move(LBytes, LArr[1], Length(LBytes)); // fail
有人可以解释为什么使用Larr和Larr [1]没有区别但LBytes [0]和LBytes之间有区别吗?
考虑以下记录:
TMyRecord = record
  b: Boolean;
  // 3 bytes of padding in here with default record alignment settings
  i: Integer;
end;
我希望实施IEqualityComparer<TMyRecord>.为了做到这一点,我想打电话TEqualityComparer<TMyRecord>.Construct.这需要提供一个TEqualityComparison<TMyRecord>没有问题的我.
但是,Construct还需要一个THasher<TMyRecord>,我想知道实现它的规范方法.该函数需要具有以下形式:
function MyRecordHasher(const Value: TMyRecord): Integer;
begin
  Result := ???
end;
我希望我需要调用BobJenkinsHash记录值的两个字段,然后将它们组合起来.这是正确的方法,我该如何组合它们?
我不使用的原因TEqualityComparison<TMyRecord>.Default是它使用CompareMem因为记录的填充而不正确.