1

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;

プログラムが直接 'finally' にジャンプするため、'ExecuteTarget' で何か問題が発生した場合、最終的な Result:= ... は決して実行されません。右?したがって、関数は FALSE を返します。私は何か間違ったことをしていますか?


PS:

  1. このコードをスレッドで使用するつもりです。
  2. 関数を Delphi に入れただけで、コンパイラは最初の行について「割り当てられた値が使用されていません」と苦情を言います。
4

3 に答える 3

12

違いは、2 番目の例では例外が呼び出し元に返されるのに対し、元の例では例外がトラップされて false が返されることです。私はそのコーディング スタイルを「なぜ失敗したかは気にせず、成功したかどうかだけを気にする」と特徴づけます。これは、場合によっては妥当な場合があります (更新をダウンロードしようとする場合など)。

そのため、コードはその点で元のコードとは大きく異なります。元のコードでは処理されない例外を呼び出し元が処理することを期待しています。

また、コンパイラの苦情は、コードに分岐がないためです-機能し、結果が2番目の割り当てによって決定されるか、例外があり、結果が無関係である場合。

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;
于 2010-08-20T02:04:09.500 に答える
2

オリジナルでは、ExecuteTarget が例外をスローした場合でも、ファイル名が存在するかどうかをテストします。

あなたの場合、ExecuteTarget が例外をスローした場合、結果は常に false です。

また、元の行をスキップしない限り、ExecuteTarget が成功し、ファイルが存在する場合resultは、決して設定されません。

于 2010-08-19T22:24:12.737 に答える
1

最初のバージョンは例外を食べるだけで、上位の呼び出し元に発生することはありません。例外を false リターンとして扱います。単純なバージョンでは、例外がスローされます。

于 2010-08-19T22:23:36.187 に答える