尝试...除了...最终在Delphi中有什么意义?

jan*_*152 5 delphi

我知道这听起来像是一个古老的愚蠢问题,但我在互联网上搜索了所有内容,但我仍然不明白一件事。我知道 try-finally 将在停止错误之前运行 finally 代码(或者在没有引发异常时不停止)并且 try-except 将在引发异常时运行except代码。但我仍然不明白的是 try-except 在 try-finally 语句中的意义。我会写一个例子

我总是做的是这样的:

a:=x.Create;
try 
  a.DoRiskyStuff;
except
  ShowMessage('Error!');
end;
a.free;
Run Code Online (Sandbox Code Playgroud)

多年来我从未使用过 finally 子句,因为我总是处理错误,而且我从来不明白将它们嵌套在一起使用的意义何在。我的解决方案有什么不好?为什么在示例中使用这样的东西很常见:

a:=x.Create;
try
  try
    a.DoRiskyStuff;
  except
    ShowMessage('Error!');
  end;
finally
  a.free;
end;
Run Code Online (Sandbox Code Playgroud)

有什么不同?当所有清理工作都可以在 try-except 之后完成时,为什么有人要使用 finally 子句?

非常感谢您的回答!

编辑:我更改了创建行,所以你们中的一些人想要为此而抨击我;)

Rud*_*uis 5

这两种结构之间有两个很大的区别。一个技术一个和一个语义一个。

技术的

从技术上讲,区别在于finally块会一直执行,即使没有异常,而except块只在出现异常时才执行。

finally 当您Exittry-finally块中提前使用退出函数时,该块甚至会被执行。

此外,该finally块并不会吞下例外,而except块一般吞下它,它只能逃避块,如果异常的类型不匹配您指定的异常类型on ... do,或者如果您手动重新raise它。

语义

except块旨在处理异常,而finally块则不是。该finally块旨在包含无论异常如何都应执行的代码,即主要是为了保护资源。这就是为什么你应该这样做:

X := TY.Create;
try
  // Code that may raise an exception.
finally
  X.Free; // Free resource, even if there was an exception.
          // Exception is NOT handled.
end;
Run Code Online (Sandbox Code Playgroud)

和:

try
  // Code that may raise an exception.
except
  // Handle the kind of exceptions you can handle.
end;
Run Code Online (Sandbox Code Playgroud)

请注意,资源保护finally不限于内存和Free. 您可以恢复/撤消/关闭任何应该恢复/撤消/关闭的内容,即关闭打开的文件、关闭打开的连接、关闭已启动的硬件、将鼠标指针恢复到以前的形式等。

因此,您还可以将其用于以下代码:

Cursor := crMultiDrag;
try
  // Code that may raise exception.
finally
  Cursor := crDefault;
end;
Run Code Online (Sandbox Code Playgroud)