【问题标题】:Use of nested "try/finally" "try/except" statements使用嵌套的“try/finally”“try/except”语句
【发布时间】:2010-08-19 22:19:38
【问题描述】:

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

如果 'ExecuteTarget' 出现问题,最终的 Result:= ... 将永远不会被执行,因为程序将直接跳转到 'finally'。对?因此,该函数将返回 FALSE。我做错了吗?


PS:

  1. 我打算在线程中使用此代码。
  2. 我只是将函数放在 Delphi 中,编译器抱怨第一行:“赋值从未使用过。”

【问题讨论】:

  • 第一个代码处结果的起始点在哪里?结果 = 真?
  • @igon:我不知道。可能只是演示/骨架代码。

标签: delphi try-finally try-except


【解决方案1】:

不同之处在于您的第二个示例将异常传递回调用者,而原始示例捕获它们并返回 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;

【讨论】:

    【解决方案2】:

    原来,如果 ExecuteTarget 抛出异常,它仍然会测试文件名是否存在。

    在你的情况下,如果 ExecuteTarget 抛出异常,结果总是 false。

    另外,除非你跳过了一行,否则如果 ExecuteTarget 成功并且文件存在,则永远不会设置 result

    【讨论】:

    • 对不起,我在你回复我的时候添加了这行代码:DeleteFile(Dest);
    • “在原来的情况下,如果 ExecuteTarget 抛出异常,它仍然会测试文件名是否存在” - 这是错误的,因为该函数实际上无法从 Internet 下载 NEW 文件。对吗?
    • @Altar:我不是在评论原始代码的智慧,只是报告它的作用。
    • > "result is always false" - 实际上,如果启用代码优化并抛出异常,'Result' 将被取消分配。
    • @Sertac:不管优化是否开启,'result'实际上是未定义的。即使在函数中赋值,由于异常逃逸给调用者,它永远不会被赋值给任何LHS变量在调用者中。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 1970-01-01
      • 2018-03-19
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      • 1970-01-01
      相关资源
      最近更新 更多