关于Delphi/Generic/array的:为什么不能编译?

我想知道下面的通用代码有什么问题(用 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 = BwhereABwas,那也将是编译器错误。数组也是如此,依此类推。

您可以使用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 库使用的命名约定。


以上是关于Delphi/Generic/array的:为什么不能编译?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>