Sometimes you want to ensure that
specific parts of an operation are completed, whether or not the operation is
interrupted by an exception. For example, when a routine acquires control of a
resource, it is often important that the resource be released, regardless of
whether the routine terminates normally. In these situations, you can use a try...finally
statement.
The following example shows how
code that opens and processes a file can ensure that the file is ultimately
closed, even if an error occurs during execution.
Reset(F);
try
... // process
file F
finally
CloseFile(F);
end;
The syntax of a try...finally
statement is
try statementList1 finally statementList2
end
where each statementList is a
sequence of statements delimited by semicolons. The try...finally
statement executes the statements in statementList1 (the try
clause). If statementList1 finishes without raising exceptions, statementList2
(the finally clause) is executed. If an exception is raised during
execution of statementList1, control is transferred to statementList2;
once statementList2 finishes executing, the exception is re-raised. If a
call to the Exit, Break, or Continue procedure causes
control to leave statementList1, statementList2 is automatically
executed. Thus the finally clause is always executed, regardless of how
the try clause terminates.
If an exception is raised but not handled in the finally clause, that exception is propagated out of the try...finally statement, and any exception already raised in the try clause is lost. The finally clause should therefore handle all locally raised exceptions, so as not to disturb propagation of other exceptions.
Raising and handling exceptions
有时想要确保操作中指定的部分被完成,不管该操作是否被异常中断。例如,当一个例程获得了对某个资源的控制时,释放该资源通常是重要的,而不管例程是否正常终止。对于这些情况,可以使用try...finally语句。
下面的例子说明了打开并处理文件的代码确保文件最终被关闭,即使在执行中可能有错误发生。
Reset(F);
try
... //处理文件F
finally
CloseFile(F);
end;
try...finally语句的语法是
try statementList1 finally statementList2
end
这里的每个语句列表statementList都是分号隔开的语句序列。try...finally语句首先试图执行statementList1中的语句(try子句)。如果statementList1完成并且没有引发任何异常,那么statementList2(finally子句)被执行。如果在statementList1执行中引发了某个异常,那么控制即可被传递到statementList2;一旦statementList2完成执行,异常就被再引发。如果有对Exit、Break或Continue等标准过程的调用导致控制离开statementList1,那么statementList2被自动执行。由此可见,无论try子句以哪一种方式终止(正常结束或由于引发异常而中断),finally子句都总是被执行。
如果异常被引发但在finally子句中未处理,那么该异常将向try...finally语句之外传播,而且在try子句中已引发的任何异常都将丢失。因此,finally子句应处理局部引发的所有异常,从而不干扰对其他异常的传播。
编者注
goto语句和try子句是不相容的:
· try子句中的goto语句不能跳转到当前try子句之外。
· try子句外的goto语句不能跳转到当前try子句之内。
这里的try子句包括try...except语句中的try子句和try...finally语句中的try子句。编译器会自动进行相关检查并报告错误信息。有关goto语句的更多信息,见goto语句。