类运算符 - 设计或缺陷区分大小写?

Posted

技术标签:

【中文标题】类运算符 - 设计或缺陷区分大小写?【英文标题】:Class operators - case sensitive by design or flaw? 【发布时间】:2017-06-11 18:33:08 【问题描述】:

在处理我称为TVersion 的记录类型时,我使用class operators。我偶然发现了一些相当令人惊讶的东西 - 运算符名称被视为区分大小写。

Delphi 的一大优点是它不区分大小写。然而,类操作符似乎违反了这条规则——至少在代码洞察力方面是这样。

奇怪的是,如果定义和实现都使用相同的大小写,则不会引发错误,无论我如何实际大写它们。但是,如果定义和实现在大小写上有任何不同,它会用红色下划线并给我一个错误:

`TVersion` does not contain a member named 'Implicit'

我在此记录中拥有的任何类运算符都会发生同样的情况。在下面的代码中,第一个 implicit 类运算符在定义中是小写的,但在实现中是大写的。其余的都是匹配的。在实现中,Implicit 带有红色下划线,我在Structure 窗口的左侧有提到的错误。

不管这些错误中的任何一个,一切都编译得很好。我没有看到案件是否匹配有任何区别。只是这个烦人的编辑器错误。它甚至没有在Messages 中显示为编译时的警告。

这是一个错误吗?还是我应该担心这些类运算符的大小写敏感性?上面链接的文档似乎没有提到它。

unit JD.Version;

interface

type
  TVersion = record
    Values: array of Integer;
    function Count: Integer;
    class operator implicit(a: TVersion): String;
    class operator Implicit(a: String): TVersion;
    class operator Equal(a, b: TVersion): Boolean;
    class operator LessThan(a, b: TVersion): Boolean;
    class operator GreaterThan(a, b: TVersion): Boolean;
    class operator GreaterThanOrEqual(a, b: TVersion): Boolean;
    class operator LessThanOrEqual(a, b: TVersion): Boolean;
    class operator NotEqual(a, b: TVersion): Boolean;
  end;

implementation

uses
  SysUtils, Math;

 TVersion 

class operator TVersion.Implicit(a: TVersion): String; //Error: 'TVersion' does not contain a member named 'Implicit'
var
  X: Integer;
begin
  Result:= '';
  for X := 0 to Length(a.Values)-1 do begin
    if X > 0 then Result:= Result + '.';
    Result:= Result + IntToStr(a.Values[X]);
  end;
end;

class operator TVersion.Implicit(a: String): TVersion;
var
  S, T: String;
  I: Integer;
begin
  S:= a + '.';
  SetLength(Result.Values, 0);
  while Length(S) > 0 do begin
    I:= Pos('.', S);
    T:= Copy(S, 1, I-1);
    Delete(S, 1, I);
    SetLength(Result.Values, Length(Result.Values)+1);
    Result.Values[Length(Result.Values)-1]:= StrToIntDef(T, 0);
  end;
end;

class operator TVersion.Equal(a, b: TVersion): Boolean;
var
  la, lb: Integer;
begin
  la := Length(a.Values);
  lb := Length(b.Values);
  if la <> lb then
    Result := False
  else if la = 0 then
    Result := True
  else
    Result := CompareMem(a.Values, b.Values, la * SizeOf(Integer));
end;

class operator TVersion.LessThan(a, b: TVersion): Boolean;
var
  la, lb, i: Integer;
begin
  la := Length(a.Values);
  lb := Length(b.Values);
  for i := 0 to Min(la, lb) - 1 do
    if a.Values[i] < b.Values[i] then   // 1.2.xxx < 1.3.xxx
      Exit(True)
    else if a.Values[i] > b.Values[i] then //1.3.xxx > 1.2.xxx
      Exit(False);
  Result := la < lb;
end;

class operator TVersion.GreaterThan(a, b: TVersion): Boolean;
begin
  Result:= b < a;
end;

class operator TVersion.GreaterThanOrEqual(a, b: TVersion): Boolean;
begin
  Result:= (a > b) or (a = b);
end;

class operator TVersion.LessThanOrEqual(a, b: TVersion): Boolean;
begin
  Result:= (a < b) or (a = b);
end;

class operator TVersion.NotEqual(a, b: TVersion): Boolean;
begin
  Result:= not(a = b);
end;

function TVersion.Count: Integer;
begin
  Result:= Length(Values);
end;

end.

这是我所看到的:

【问题讨论】:

这是 Code Insight 中的一个错误(或任何导致对象检查器中的错误消息的原因)。如果代码可以编译,一切都很好,这也意味着该语言区分大小写,甚至不区分 WRT 类运算符。只是执行 Code Insight 的(更有限和不同的)编译器。 @Rudy 确实,我想得那么远,但我很想知道这是否是由于未能清理一些旧语言限制的结果......例如在某些时候区分大小写过去。或者这可能是某些平台的要求......? 不,这不是未能清除旧语言限制的结果。 Code Insight 简直是有问题,即使在东京,它已经变得更好了一点,但仍然不是完美无缺的。我经常收到找不到System.SysUtilsSystem.Classes或类似的消息,或者Exception没有成员Message等。我想这更像是一样的。 代码洞察力很糟糕。代码编译。 其他的也可能有模式。错误不是随机发生的,它们只是编译不完整的结果,因为 Code Insight 编译器可能会偷工减料。 【参考方案1】:

这是Error Insight 后台编译器中的一个错误。语言本身不区分大小写。

【讨论】:

外部导入和导出也区分大小写。但就像Register 这不是真正的语言。该语言确实不区分大小写。 确实如此。这就是我的观点。我说该语言不区分大小写。你的回答不是这样。 @David,然后写你自己的 :) 呃,我在评论你的。还是你觉得评论不对? 我只是指出了一个非常小的问题。编辑答案很容易。我们不需要另一个。

以上是关于类运算符 - 设计或缺陷区分大小写?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 区分大小写的比较运算符

在运行时与 VB.NET LIKE 运算符进行大小写(不)敏感比较(无选项比较)

mysql模糊查询区分大小写

是否有 C# 不区分大小写的等于运算符?

SQL Server 的 LIKE 运算符是不是区分大小写?

实体框架核心 - 包含区分大小写还是不区分大小写?