Joh*_*ica 3 delphi operator-overloading set
我正在使用记录来封装两个异常集.
我已经放入运算符以允许将任一组分配给记录.这样做会清除另一组.
但是我不能指定一个空集.
请参阅以下示例代码:
Program test;
{$Apptype console}
type
TSomeThing = (a,b,c);
TOtherThing = (x,y,z);
TSomeThings = set of TSomething;
TOtherThings = set of TOtherThing;
TSomeRecord = record
strict private
Fa: TSomeThings;
Fb: TOtherThings;
public
class operator Implicit(a: TSomeThings): TSomeRecord;
class operator Implicit(a: TOtherThings): TSomeRecord;
end;
implementation
class operator TSomeRecord.Implicit(a: TSomeThings): TSomeRecord;
begin
Result.Fa:= a;
Result.Fb:= [];
end;
class operator TSomeRecord.Implicit(a: TOtherThings): TSomeRecord;
begin
Result.Fa:= [];
Result.Fb:= a;
end;
var
SomeRec: TSomeRecord;
begin
SomeRec:= [];
end.
Run Code Online (Sandbox Code Playgroud)
[dcc64 Error] InstructionList.pas(512):E2010不兼容类型:'TSomeRecord'和'Set'
我怎么做到这样我可以将空集分配给我的记录?
我可以滥用隐式运算符来允许SomeRec:= nil;,但这看起来非常难看.
编译器无法判断您是表示空集TSomeThing还是空集TOtherThing.您可以声明类型化常量以允许编译器解决重载:
const
EmptySomeThings: TSomeThings = [];
EmptyOtherThings: TOtherThings = [];
Run Code Online (Sandbox Code Playgroud)
然后按照您的预期编译和解决以下分配:
SomeRec:= EmptySomeThings;
SomeRec:= EmptyOtherThings;
Run Code Online (Sandbox Code Playgroud)
当然,您知道其中任何一个都具有相同的效果,因为Implicit运算符的实现设置了一个字段,并清除了另一个字段.但编译器无法知道这一点.
如果您希望清除记录的两个成员,您可以随时使用:
SomeRec:= Default(TSomeRecord);
Run Code Online (Sandbox Code Playgroud)
我个人可能会在这样的静态类方法中将其包装起来:
class function Default: TSomeRecord; static;
....
class function TSomeRecord.Default: TSomeRecord;
begin
Result := Default(TSomeRecord);
end;
Run Code Online (Sandbox Code Playgroud)
然后你可以写:
SomeRec:= TSomeRecord.Default;
Run Code Online (Sandbox Code Playgroud)
在一个理想的世界中,你可以在类型中声明一个常量,但是语言设计者没有想到这一点,而且遗憾的是它是不可能的.
更新
Rudy在评论中正确地指出,常量可以通过记录助手添加到记录类型中.这对我来说是新闻,因为我错误地认为助手只能添加方法.这就是我喜欢的Stack Overflow.即使你认为自己了解得很好,也总是可以获得更多的知识.谢谢鲁迪.
所以你可以写:
type
TSomeRecordHelper = record helper for TSomeRecord
public
const
Default: TSomeRecord = ();
end;
Run Code Online (Sandbox Code Playgroud)