我知道这听起来像是一个古老的愚蠢问题,但我在互联网上搜索了所有内容,但我仍然不明白一件事。我知道 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 子句?
非常感谢您的回答!
编辑:我更改了创建行,所以你们中的一些人想要为此而抨击我;)
这两种结构之间有两个很大的区别。一个技术一个和一个语义一个。
从技术上讲,区别在于finally块会一直执行,即使没有异常,而except块只在出现异常时才执行。
finally 当您Exit在try-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)
| 归档时间: |
|
| 查看次数: |
4851 次 |
| 最近记录: |