10

私は次のように再帰的にシーケンスを定義するのが好きです。

let rec startFrom x =
    seq {
        yield x;
        yield! startFrom (x + 1)
    }

このような再帰シーケンスを実際に使用する必要があるかどうかはわかりません。は末尾再帰のようにyield! 見えますが、別のIEnumerable内から呼び出されているため、100%確実ではありません。私の見解では、コードは呼び出しごとにIEnumerableのインスタンスを閉じずに作成します。これにより、実際にはこの関数もメモリをリークします。

この関数はメモリをリークしますか?さらに言えば、それは「末尾再帰」でさえありますか?

[編集して追加]:答えを求めてNProfをいじくり回していますが、SOでの再帰シーケンスの実装に関する技術的な説明を得ることが役立つと思います。

4

3 に答える 3

-2

メモリをリークすることはなく、無限のシーケンスを生成するだけですが、シーケンスは IEnumerables であるため、メモリを気にせずに列挙できます。再帰がシーケンス生成関数内で発生するという事実は、再帰の安全性に影響しません。デバッグ モードでは、完全なデバッグを可能にするためにテール コールの最適化が無効になっている可能性がありますが、リリース時には問題はまったくないことに注意してください。

于 2009-06-19T20:55:33.287 に答える