Class 运算符 - 区分大小写是设计还是缺陷?
Class operators - case sensitive by design or flaw?
在处理我称为 TVersion
的记录类型时,我使用了 class operators。我偶然发现了一些相当令人惊讶的事情——运算符名称被视为区分大小写。
Delphi 的一大优点是 不区分大小写。但是,class 运算符似乎违反了这条规则 - 至少在代码洞察力方面。
奇怪的是,如果定义和实现都使用相同的大小写,则不会出现错误,无论我实际如何将它们大写。但是,如果定义和实现在大小写上有任何不同,它会用红色下划线并给我一个错误:
`TVersion` does not contain a member named 'Implicit'
我在此记录中的任何 class 运算符都会发生同样的情况。在下面的代码中,第一个 implicit
class 运算符在定义中是小写,但在实现中是大写。其余的都是匹配的。在实现中,Implicit
带有红色下划线,我在 Structure
window.
左侧有提到的错误
不管这些错误中的任何一个,一切都编译得很好。我没有看到案例是否匹配有任何区别。只是这个烦人的编辑器错误。它甚至没有在 Messages
中显示为编译时的警告。
这是一个错误吗?或者我应该关心这些 class 运算符的区分大小写吗?上面链接的文档似乎没有提到它。
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.
这是我看到的:
这是 Error Insight 后台编译器中的错误。语言本身不区分大小写。
在处理我称为 TVersion
的记录类型时,我使用了 class operators。我偶然发现了一些相当令人惊讶的事情——运算符名称被视为区分大小写。
Delphi 的一大优点是 不区分大小写。但是,class 运算符似乎违反了这条规则 - 至少在代码洞察力方面。
奇怪的是,如果定义和实现都使用相同的大小写,则不会出现错误,无论我实际如何将它们大写。但是,如果定义和实现在大小写上有任何不同,它会用红色下划线并给我一个错误:
`TVersion` does not contain a member named 'Implicit'
我在此记录中的任何 class 运算符都会发生同样的情况。在下面的代码中,第一个 implicit
class 运算符在定义中是小写,但在实现中是大写。其余的都是匹配的。在实现中,Implicit
带有红色下划线,我在 Structure
window.
不管这些错误中的任何一个,一切都编译得很好。我没有看到案例是否匹配有任何区别。只是这个烦人的编辑器错误。它甚至没有在 Messages
中显示为编译时的警告。
这是一个错误吗?或者我应该关心这些 class 运算符的区分大小写吗?上面链接的文档似乎没有提到它。
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.
这是我看到的:
这是 Error Insight 后台编译器中的错误。语言本身不区分大小写。