2010-08-19 75 views
1

我看到這個代碼在這裏貼在計算器上:使用嵌套「嘗試/終於」「嘗試/除」報表

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'中出現錯誤,將永遠不會執行,因爲程序將直接跳轉到'finally'。對?所以,該函數將返回FALSE。難道我做錯了什麼?


PS:

  1. 我打算在一個線程中使用此代碼。
  2. 我只是把這個函數放在Delphi和編譯器有關第一行的抱怨上:「從未使用過的值」。
+0

哪裏是在第一個代碼的結果的啓動?結果=真? – garik 2010-08-19 22:26:36

+0

@igon:我不知道。可能只是演示/骨架代碼。 – Ampere 2010-08-19 22:34:24

回答

12

區別在於你的第二個例子將異常傳遞給調用者,而原始陷阱將它們陷阱並返回false。我將這種編碼描述爲「我不在乎它爲什麼失敗,我只關心它是否成功」。在某些情況下這可能是合理的(例如嘗試下載更新)。

因此,您的代碼與原始代碼非常不同 - 您期望調用者能夠處理原始代碼無法處理的異常。

此外,編譯器投訴是因爲代碼中沒有分支 - 如果作品和結果是由第二個賦值確定的,或者您有異常並且Result是不相關的。

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; 
1

第一個版本只是吃掉了異常並且從不向上層調用者提出,它將異常視爲虛假返回。對於你的簡單版本,異常將被拋出。

2

在原來,如果ExecuteTarget拋出異常,它仍然會測試filename的存在。

在你的,如果ExecuteTarget拋出一個異常,結果總是爲false。

此外,除非您在原始上跳過一行,否則如果ExecuteTarget成功且文件存在,則result從不設置。

+0

對不起,我在回答我的時候添加了一行代碼:DeleteFile(Dest); – Ampere 2010-08-19 22:31:14

+0

「在原來,如果ExecuteTarget拋出一個異常,它仍然會測試文件名存在」 - 這是錯誤的,因爲該函數實際上無法從互聯網下載NEW文件。對? – Ampere 2010-08-19 22:32:33

+0

@Altar:我不是在評論原始代碼的智慧,不知道它做了什麼。 – 2010-08-19 22:41:56