13

私のように、While (True) ループの場所で震えているなら、あなたもそれをリファクタリングする最善の方法について長い間真剣に考えてきたに違いありません。私はいくつかの異なる実装を見てきましたが、タイマーとデリゲートの組み合わせなど、他のどの実装よりも優れているものはありません。

では、恐ろしい While (True) ループをリファクタリングするために思いついた、または見た最良の方法は何ですか?

編集:いくつかのコメントが述べたように、私の意図は、この質問が「無限ループ」リファクタリングであることでした。たとえば、停止条件が OnStop または致命的な例外のみである Windows スタイルのサービスを実行することです。

4

12 に答える 12

64

私の好みは

start:

   // code goes here

goto start;

これは意図を最も明確に表しています。コーディング標準を超えて頑張ってください。(これが私にどれだけのカルマを費やすのだろうか)。

于 2008-10-28T20:02:23.643 に答える
27

while(true)ループを本当にリファクタリングする必要がありますか?時々それはコーディング標準であり、開発者のほとんどはこの構造に慣れています。このコードをリファクタリングする方法を真剣に考える必要がある場合は、リファクタリングすることをお勧めしますか?

後藤は、コーディング標準では黒い羊でした。gotoがコードをはるかに読みやすく短くしたアルゴリズムに出会いました。リファクタリングする価値がない場合もあります(またはgotoを使用する方がよい場合もあります)。

一方、ほとんどの場合、 while(true)を回避できます。

于 2008-10-28T20:22:22.633 に答える
23

それについて何がそんなに恐ろしいのですか?一般的な中断条件を見つけて、ループの先頭になるようにリファクタリングしてみてください。それが不可能な場合は、問題ありません。

于 2008-10-28T19:10:38.457 に答える
18

while(true) ループに遭遇すると、どちらかがわかります

  1. ループの上部 (または下部) でブレーク条件をテストするのは容易ではありません。
    • 複数のブレーク条件があり、
    • または、以前のプログラマーが怠惰すぎてループを適切に因数分解できませんでした。

1 と 2 は、while(true) に固執することを意味します。(私は を使用しますfor(;;)が、それは私の意見ではスタイルの問題です。) 私は別のポスターを使用していますが、なぜこれを恐れるのですか? ループを「適切に」ロールするためにフープをジャンプする、拷問されたループが怖いです。

于 2008-10-28T19:18:47.350 に答える
14

True を、ループから抜け出すために使用する条件に置き換えます。

サービスまたはバックグラウンド スレッドの場合は、次を使用できます。

volatile bool m_shutdown = false;
void Run()
{
    while (!m_shutdown)
    { ... }
}
于 2008-10-28T19:13:03.897 に答える
13

リファクタリングする理由 そして、この構造の何が「恐ろしい」のでしょうか? 広く使われており、よく理解されています。

壊れていない場合は、修正しないでください。

于 2008-10-28T19:33:24.853 に答える
8

「永久に実行中」の状況は、より大きなステート マシンの一部である場合があります。多くの組み込みデバイス (run-forever ループを使用) は、実際には永久に実行されません。多くの場合、いくつかの動作モードがあり、それらのモード間で順序付けられます。

ヒート ポンプ コントローラーを構築したとき、少しの間実行される電源投入時セルフ テスト (POST) モードがありました。次に、すべてのゾーンとサーモスタットなどを把握するまで実行される予備的な環境収集モードがありました.

一部のエンジニアは、次に来るのは「run-forever」ループだと主張しました。それほど単純ではありませんでした。実際には、いくつかの動作モードがひっくり返ったり、フロップしたりしていました。暖房、霜取り、冷房、アイドリング、その他のものがありました。

私の好みは、「永久」ループを実際には 1 つの動作モードとして扱うことです。将来のある時点で他の動作モードが存在する可能性があります。

someMode= True
while someMode:
    try:
        ... do stuff ...
    except SomeException, e:
        log.exception( e )
        # will keep running
    except OtherException, e:
        log.info( "stopping now" )
        someMode= False

someMode状況によっては、これまでに に設定されたものはありませんFalse。しかし、私は、将来のバージョンでモード変更があるふりをするのが好きです.

于 2008-10-28T19:23:17.793 に答える
7
#define ever 1
for (;ever;)

?

まあ、そのままにしておいてください。(true) はおそらくあなたが得ようとしているのと同じくらい読みやすいです..

于 2008-10-28T19:51:38.657 に答える
5

えーと、リファクタリングに……。

  • 無限ループを無限再帰に置き換えます:-)

まあ、テール呼び出しをサポートする言語があれば....

于 2008-10-28T19:14:58.310 に答える
3

プログラムフローが完全に中止されるまで無期限に継続したい場合は、while (true) に問題はないと思います。最近、while (true) と thread.sleep を組み合わせて毎分起動し、サードパーティのデータ サービスをポーリングして新しいレポートを取得する .NET データ コレクション サービスで、この問題に遭遇しました。タイマーとデリゲートを使用してリファクタリングすることも検討しましたが、最終的にはこれが最も単純で読みやすい方法であると判断しました。10 回中 9 回は明らかなコード臭ですが、終了条件がない場合、なぜ事態がさら​​に難しくなるのでしょうか?

于 2008-10-28T19:22:02.053 に答える
1

無限ループがウィンドウ内に含まれていて、ウィンドウで死ぬときは気にしません。

ハッセルホフ再帰を考えてみてください。

于 2008-10-28T19:35:55.940 に答える
-2
void whiletrue_sim(void)
  {
    //some code
    whiletrue_sim();
  }

警告: スタックがオーバーフローする可能性があります。

于 2016-05-17T22:12:27.923 に答える