arrays - 关于 Delphi/Generic/array 的 : why this doesn't compile?

标签 arrays delphi generics

我想知道下面的通用代码(用 Delphi 10.4.1 编写)有什么问题。 此外,还有另一种方法可以实现相同的目标吗?我的意思是在数组中搜索 (我知道我应该使用集合)。提前致谢!

问候

type
TDelphiExtention = class
public
  class function inside<T>(const value : T; const arr : array of T) : boolean;
end;

class function TDelphiExtention.inside<T>(const value : T; const arr : array of T) : boolean;
var
  i : integer;

begin
  result := true;
  for i := Low(arr) to High(arr) do begin
    if (arr[i] = value) then begin // E2015 Operator not applicable to this operand type !!!
      exit;
    end;
  end;

  result := false; // Not found
end;

// This one compiles like a charm... But is not generic :(
function inside(const value : integer; const arr : array of integer) : boolean;
var
  i : integer;

begin
  result := true;
  for i := Low(arr) to High(arr) do begin
    if (arr[i] = value) then begin
      exit;
    end;
  end;

  result := false; // Not found
end;

最佳答案

T 实际上可以是任何东西。编译器不知道如何比较给定任意类型的相等性。例如,假设 T 是一条记录。如果您尝试编写 A = B,其中 AB 属于该记录类型,那也将是一个编译器错误。对于数组等也是如此。

您可以使用 System.Generics.Defaults 单元的工具来获得相等比较器:

class function TDelphiExtention.inside<T>(const value: T;
  const arr: array of T): boolean;
var
  i: integer;
  comparer: IEqualityComparer<T>;
begin
  comparer := TEqualityComparer<T>.Default;

  for i := Low(arr) to High(arr) do
  begin
    if comparer.Equals(arr[i], value) then
    begin
      result := true;
      exit;
    end;
  end;

  result := false; // Not found
end;

请注意,并非所有类型都具有适当的相等比较器,因此您可能希望提供一个重载以接受相等比较器作为参数。

class function TDelphiExtention.inside<T>(const value: T;
  const arr: array of T; comparer: IEqualityComparer<T>): boolean;
var
  i: integer;
begin
  for i := Low(arr) to High(arr) do
  begin
    if comparer.Equals(arr[i], value) then
    begin
      result := true;
      exit;
    end;
  end;

  result := false; // Not found
end;

FWIW,您的方法最好命名为 Contains,因为这符合大多数其他 Delphi 库使用的命名约定。

关于arrays - 关于 Delphi/Generic/array 的 : why this doesn't compile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65630440/

相关文章:

c# - 创建IQueryable <T>的通用过滤器,其中该过滤器使用ISomeInterface中定义的属性

reactjs - React TSX 文件中的泛型

javascript - 单击href并将数据存储到输入框中

基于另一个对象数组的Javascript过滤器数组

delphi - 如何向 FireMonkey 工具栏添加按钮?

android - 使用 Delphi 10 在 Android 上错误地返回空文件列表

c# - 该类型不能用作泛型类型或方法中的类型 'T'。没有从到的隐式引用转换

javascript - 遍历多维 JSON 数据

c - 错误 : expression must be a modifiable l value

delphi - 为什么 EOutOfResources 中会泄漏内存?