使用嵌套的“try/finally” “尝试/除外”声明
我在 StackOverflow 上看到过这段代码:
with TDownloadURL.Create(nil) do
try
URL := 'myurltodownload.com';
filename := 'locationtosaveto';
try
ExecuteTarget(nil);
except
result := false;
end;
if not FileExists(filename) then
result := false;
finally
free;
end;
不能将其简化为如下所示:
Result:= FALSE; <--------- Compiler complains
DeleteFile(Dest);
dl:= TDownloadURL.Create(NIL);
TRY
dl.URL:= URL;
dl.FileName:= Dest;
dl.ExecuteTarget(NIL);
Result:= FileExists(Dest);
FINALLY
dl.Free;
END;
The Final Result:= ... 如果“ExecuteTarget”中出现问题,则永远不会执行,因为程序将直接跳转到“finally” 。正确的?因此,该函数将返回 FALSE。我做错了什么吗?
PS:
- 我打算在线程中使用这段代码。
- 我只是将函数放入 Delphi 中,编译器抱怨第一行:“分配的值从未使用过”。
I have seen this code posted here on StackOverflow:
with TDownloadURL.Create(nil) do
try
URL := 'myurltodownload.com';
filename := 'locationtosaveto';
try
ExecuteTarget(nil);
except
result := false;
end;
if not FileExists(filename) then
result := false;
finally
free;
end;
Can't it be simplified to look like:
Result:= FALSE; <--------- Compiler complains
DeleteFile(Dest);
dl:= TDownloadURL.Create(NIL);
TRY
dl.URL:= URL;
dl.FileName:= Dest;
dl.ExecuteTarget(NIL);
Result:= FileExists(Dest);
FINALLY
dl.Free;
END;
The final Result:= ... will never be executed if something went wrong in 'ExecuteTarget' because the program will jump directly to 'finally'. Right? So, the function will return FALSE. Am I doing something wrong?
PS:
- I intend to use this code in a thread.
- I just put the function in Delphi and the compiler complains about the first line: "Value assigned never used."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不同之处在于,第二个示例将异常传递回调用者,而原始示例则捕获异常并返回 false。我将这种编码风格描述为“我不关心它为什么失败,我只关心它是否成功”。在某些情况下这可能是合理的(例如尝试下载更新)。
因此,您的代码在这方面与原始代码非常不同 - 您期望调用者处理原始代码不处理的异常。
另外,编译器的抱怨是因为您的代码中没有分支 - 要么工作并且结果由第二个赋值确定,要么您有异常并且结果不相关。
The difference is that your second example passes exceptions back to the caller, while the original traps them and returns false. I'd characterise that style of coding as "I don't care why it failed, I only care whether it succeeded". Which can be reasonable in some cases (like trying to download an update).
So your code is very different from the original in that way - you are expecting the caller to handle exceptions that the original code does not.
Also, the compiler complaint is because there's no branch in your code - either if works and result is determined by the second assignment or you have an exception and Result is irrelevant.
在原来的情况下,如果 ExecuteTarget 抛出异常,它仍然会测试文件名是否存在。
在你的例子中,如果 ExecuteTarget 抛出异常,则结果始终为 false。
另外,除非您在原始版本中跳过一行,否则如果 ExecuteTarget 成功并且文件存在,则永远不会设置
result
。In the original, if ExecuteTarget throws an exception, it will still test of filename exists.
In yours, if ExecuteTarget throws an exception, result is always false.
Also, unless you skipped a line, on the original, if ExecuteTarget succeeds and the file exists,
result
is never set.第一个版本只是吃掉异常,从不向上层调用者引发,它将异常视为错误返回。对于您的简单版本,异常将被抛出。
The first version just eat the exception and never raise to upper callers, it treat exception as false return. For your simple version, exception will be thrown out.