使用嵌套的“try/finally” “尝试/除外”声明

发布于 2024-09-15 00:09:20 字数 843 浏览 8 评论 0原文

我在 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:

  1. 我打算在线程中使用这段代码。
  2. 我只是将函数放入 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:

  1. I intend to use this code in a thread.
  2. I just put the function in Delphi and the compiler complains about the first line: "Value assigned never used."

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风透绣罗衣 2024-09-22 00:09:20

不同之处在于,第二个示例将异常传递回调用者,而原始示例则​​捕获异常并返回 false。我将这种编码风格描述为“我不关心它为什么失败,我只关心它是否成功”。在某些情况下这可能是合理的(例如尝试下载更新)。

因此,您的代码在这方面与原始代码非常不同 - 您期望调用者处理原始代码不处理的异常。

另外,编译器的抱怨是因为您的代码中没有分支 - 要么工作并且结果由第二个赋值确定,要么您有异常并且结果不相关。

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 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.

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;
清醇 2024-09-22 00:09:20

在原来的情况下,如果 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.

腻橙味 2024-09-22 00:09:20

第一个版本只是吃掉异常,从不向上层调用者引发,它将异常视为错误返回。对于您的简单版本,异常将被抛出。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文