Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何使用重载运算符为记录分配空集_Delphi_Set_Operator Overloading - Fatal编程技术网

Delphi 如何使用重载运算符为记录分配空集

Delphi 如何使用重载运算符为记录分配空集,delphi,set,operator-overloading,Delphi,Set,Operator Overloading,我正在使用一个记录来封装两个伪装集。 我已经输入了运算符,允许将任意一个集合赋值到记录中。这样做将清除另一组。 但是我不能分配一个空集合 请参见以下示例代码: Program test; {$Apptype console} type TSomeThing = (a,b,c); TOtherThing = (x,y,z); TSomeThings = set of TSomething; TOtherThings = set of TOtherThing; TSomeRe

我正在使用一个记录来封装两个伪装集。
我已经输入了运算符,允许将任意一个集合赋值到记录中。这样做将清除另一组。
但是我不能分配一个空集合

请参见以下示例代码:

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.
[dcc64错误]指令列表.pas(512):E2010不兼容类型:“TSomeRecord”和“Set”

我如何制作它,以便将空集分配给我的记录?

我可以滥用隐式运算符来允许
SomeRec:=nil,但看起来很难看

编译器无法判断您指的是一组空的
TSomeThing
还是一组空的
TOtherThing
。您可以声明类型化常量以允许编译器解决重载问题:

const
  EmptySomeThings: TSomeThings = [];
  EmptyOtherThings: TOtherThings = [];
然后,按照您的预期编译并解决以下任务:

SomeRec:= EmptySomeThings;
SomeRec:= EmptyOtherThings;
当然,您知道其中任何一个都有相同的效果,因为
隐式
操作符的实现设置了一个字段,并清除了另一个字段。但是编译器不能知道这一点

如果希望清除记录的两个成员,则始终可以使用:

SomeRec:= Default(TSomeRecord);
我个人可能会将其封装在一个静态类方法中,如下所示:

class function Default: TSomeRecord; static;
....
class function TSomeRecord.Default: TSomeRecord;
begin
  Result := Default(TSomeRecord);
end;
然后你可以写:

SomeRec:= TSomeRecord.Default;
在理想情况下,您可以在类型中声明一个常量,但语言设计者没有想到这一点,很遗憾,这是不可能的

更新

鲁迪在评论中正确地指出,常数可以通过记录助手添加到记录类型中。这对我来说是个新闻,因为我错误地认为助手只能添加方法。这就是我喜欢堆栈溢出的地方。即使你认为自己对某件事了如指掌,也总有获得更多知识的空间。谢谢你,鲁迪

所以你可以写:

type
  TSomeRecordHelper = record helper for TSomeRecord
  public
    const
      Default: TSomeRecord = ();
  end;

编译器无法识别
[]
是什么。那是
t某事物
还是
与之相关的事物
?甚至我们也不能说。只有你知道你要在那里分配什么。不知怎的,
default()
被允许向严格的私有成员写入内容让人觉得奇怪。我相信这种感觉会过去的。我会将您的最后一行缩短为:
SomeRec.Clear
使用内联方法。@Johan
Default
没有写入任何内容-它正在创建该类型的默认初始化实例。编译后的应用程序需要能够做到这一点,例如,在构造期间分配和初始化类字段。如果您关心记录的分配,请复制该记录的私有成员。。。嗯,记录是值类型。如果不复制记录的成员,任务还能起什么作用呢?@Johan那么,假设你制作了一个
TList
。然后您可能会想写:
List[i]。清除
。那没什么用。它所做的只是清除临时内容,保持列表内容不变。@DavidHeffernan不道歉。有时候你会得到熊……有时候熊会得到你;)我不是100%确定,现在没有时间检查,但是从某个Delphi版本开始,您可以使用记录帮助器在定义类型后偷偷地将记录常量输入。