加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

德尔福的“免费”做什么?

发布时间:2020-12-15 09:45:04 所属栏目:大数据 来源:网络整理
导读:我找到了以下代码片段 here: with TClipper.Create do try AddPolygon(subject,ptSubject); AddPolygon(clip,ptClip); Execute(ctIntersection,solution); finally free; end 只是好奇,免费声明/功能(终于和结束之间)在这里做什么?谷歌没有帮助. 解决方法
我找到了以下代码片段 here:

with TClipper.Create do
  try
    AddPolygon(subject,ptSubject);
    AddPolygon(clip,ptClip);
    Execute(ctIntersection,solution);
  finally
    free;
  end

只是好奇,免费声明/功能(终于和结束之间)在这里做什么?谷歌没有帮助.

解决方法

代码

with TClipper.Create do
  try
    AddPolygon(subject,solution);
  finally
    free;
  end

是简写

with TClipper.Create do
begin
  try
    AddPolygon(subject,solution);
  finally
    free;
  end;
end;

TClipper.Create创建一个TClipper类型的对象,并返回它,并且with语句(与大多数语言一样)允许您在不使用NameOfObject.MethodOrProperty语法的情况下访问此TClipper对象的方法和属性.

(一个更简单的例子:

MyPoint.X := 0;
MyPoint.Y := 0;
MyPoint.Z := 0;
MyPoint.IsSet := true;

可以简化为

with MyPoint do
begin
  X := 0;
  Y := 0;
  Z := 0;
  IsSet := true;
end;

)

但在您的情况下,您永远不需要将TClipper对象声明为变量,因为您创建它并可以通过with构造访问其方法和属性.

所以你的代码几乎是平等的

var
  Clipper: TClipper;

Clipper := TClipper.Create;
Clipper.AddPolygon(subject,ptSubject);
Clipper.AddPolygon(clip,ptClip);
Clipper.Execute(ctIntersection,solution);
Clipper.Free;

第一行Clipper:= TClipper.Create创建一个TClipper对象.以下三行与此对象一起使用,然后Clipper.Free销毁该对象,释放RAM,还可能释放TClipper对象使用的CPU时间和OS资源.

但是上面的代码并不好,因为如果在AddPolygon或Execute中发生错误(创建异常),那么Clipper.Free永远不会被调用,因此你有内存泄漏.为了防止这种情况,Delphi使用try … finally … end构造:

Clipper := TClipper.Create;
try
  Clipper.AddPolygon(subject,ptSubject);
  Clipper.AddPolygon(clip,ptClip);
  Clipper.Execute(ctIntersection,solution);
finally
  Clipper.Free;
end;

即使创建了异常,即使在try和finally之间调用Exit,也可以保证finally和end之间的代码运行.

梅森所意味的是,由于标识符的冲突,有时构造可能是……大脑中的一个颜料.例如,考虑一下

MyObject.Caption := 'My test';

如果你在with构造中写这个,即如果你写

with MyObect do
begin
  // A lot of code
  Caption := 'My test';
  // A lot of code
end;

然后你可能会感到困惑.实际上,最常见的是Caption:=更改当前表单的标题,但现在,由于with语句,它将改变MyObject的标题.

更糟糕的是,如果

MyObject.Title := 'My test';

并且MyObject没有Caption属性,你忘了这个(并认为该属性被称为Caption),然后

MyObject.Caption := 'My test';

甚至不会编译,而

with MyObect do
begin
  // A lot of code
  Caption := 'My test';
  // A lot of code
end;

将编译得很好,但它不会做你期望的.

另外,构造如

with MyObj1,MyObj2,...,MyObjN do

或嵌套语句,如

with MyConverter do
  with MyOptionsDialog do
    with MyConverterExtension do
      ..

会产生很多冲突.

捍卫The With Statement

我注意到,几乎有一个共识(至少在这个帖子中),with语句比邪恶更好.虽然我知道可能存在混淆,并且已经堕落了几次,但我不能同意.仔细使用with语句可以使代码看起来更漂亮.这减少了“barfcode”引起混淆的风险.

例如:

相比

var
  verdata: TVerInfo;

verdata := GetFileVerNumbers(FileName);
result := IntToStr(verdata.vMajor) + '.' + IntToStr(verdata.vMinor) + '.' + IntToStr(verdata.vRelease) + '.' + IntToStr(verdata.vBuild);

with GetFileVerNumbers(FileName) do
  result := IntToStr(vMajor) + '.' + IntToStr(vMinor) + '.' + IntToStr(vRelease) + '.' + IntToStr(vBuild);

绝对没有混淆的风险,我们不仅在最后一种情况下保存了一个临时变量 – 它也更具可读性.

或者这个非常非常标准的代码:

with TAboutDlg.Create(self) do
  try
    ShowModal;
  finally
    Free;
  end;

究竟混淆的风险在哪里?从我自己的代码中,我可以提供数百个with语句的示例,所有这些都是简化代码.

此外,如上所述,只要您知道自己在做什么,就没有使用过的风险.但是如果你想在上面的例子中使用with语句和MyObject,那么,在with语句中,Caption等于MyObject.Caption.那你怎么改变表格的标题呢?简单!

with MyObject do
begin
  Caption := 'This is the caption of MyObject.';
  Self.Caption := 'This is the caption of Form1 (say).';
end;

另一个有用的地方是使用属性或函数结果时,需要花费很多时间来执行.

要使用上面的TClipper示例,假设您有一个TClipper对象列表,其中包含一个返回特定TabSheet的限幅器的慢速方法.

理想情况下,您应该只调用此getter一次,因此您可以使用显式局部变量,也可以使用隐式局部变量.

var
  Clipper : TClipper;
begin
  Clipper := ClipList.GetClipperForTab(TabSheet);
  Clipper.AddPolygon(subject,solution);
end;

要么

begin
  with ClipList.GetClipperForTab(TabSheet)do
  begin
    AddPolygon(subject,solution);
  end;
end;

在这种情况下,任何一种方法都可以,但在某些情况下,通常在复杂的条件下,a可以更清楚.

var
  Clipper : TClipper;
begin
  Clipper := ClipList.GetClipperForTab(TabSheet);
  if (Clipper.X = 0) and (Clipper.Height = 0) and .... then
    Clipper.AddPolygon(subject,ptSubject);
end;

要么

begin
  with ClipList.GetClipperForTab(TabSheet) do
    if (X = 0) and (Height = 0) and .... then
      AddPolygon(subject,ptSubject);
end;

最终是个人品味的问题.我通常只会使用范围非常窄的with,而不会嵌套它们.以这种方式使用它们是减少barfcode的有用工具.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读