4

C ++、Javaなどの他の言語に移植したい、美しくエレガントな(IMO)コードを書いています。

私が直面している問題は2つあります。

  • コードは使用しますyield
  • コードは非常に再帰的です

手で取り除くことyield可能ですが、非常に面倒です。プロセスは非常に機械的で、明らかに自動化可能です。
同時に、C# コンパイラがこれを変換するステート マシンは非常に醜く、移植には実質的に使用できません。(逆コンパイルしてみましたが、読めません。)

手で取り除くためにこれに何日も費やす以外に、他に選択肢はありますyieldか?
または、ブロックを (読み取り可能な) ステート マシンに変換できる何らかのツールがありyield、それを通常のコードのように移植できますか?


私が「高度に再帰的」とは何を意味するのか知りたい場合は、以下のコードは基本的にコードの構造です (実際は 66 行しかありません。それほど長い関数ではありません)。

static IEnumerable<ReturnType> MyRecursiveYielder(args)
{
    if (blah1) yield return foo;
    else if (blah2)
        foreach (var foo1 in foo2.Blah())
            foreach (var item in MyRecursiveYielder(moreArgs))
                yield return item;
    else
    {
        var state = new State();
        foreach (var item in blah)
            foreach (var item2 in MyRecursiveYielder(otherArgs))
                foreach (var item3 in blah3)
                {
                    foreach (var result in MyRecursiveYielder(yetMoreArgs)))
                        yield return result;
                    foobar1();
                }
        while (condition)
            foreach (var foo in blah)
                foreach (var result in MyRecursiveYielder(argh)))
                {
                    if (condition2)
                        foreach (var result in MyRecursiveYielder(almostThere)))
                            yield return result;
                    foobar2();
                }
    }
}
4

2 に答える 2

1

yield が達成することは、コルーチンに近いものです。それらをサポートする言語に移植できるはずです。残念ながら、そうする言語はほとんどありません。私はエイダがそれらを持っていると信じています。

次のステップは繊維です。Win32 API はファイバーを公開するため、C++ の場合はオプションになる可能性があります。Java用ではないと思います。

簡単な答え: ターゲット プラットフォームのコルーチンまたはファイバーの可用性を調査します。

于 2012-10-22T09:51:37.610 に答える
0

解決策を見つけたと思います。ほとんどの場合、LINQ を使用できます。そうすればyield、最初のいくつかのケースでは何もする必要がありません。これらのケースはステートフルではないからです。

ステートフル イールド (つまり、最後のもの) が問題です。しかし、熟睡した後、私の「ステートフル」yieldコードは基本的に単なるツリー検索 (正確には幅優先検索) であることに気付きました。基本的にこのコードのように。

IEnumerable<T>したがって、幅優先検索を実行する独自のクラスを簡単に作成できます。つまり、伝達関数が与えられた(T parenet) => (IEnumerable<T> children)場合、子を 1 つずつ出力し、何もなくなるまで検索を続けます。

それが機能する場合、コード構造を本質的に同じに保ちながら、すべてのsを取り除くことができます。つまりyield、はるかに読みやすく、移植しやすくなります。

于 2012-10-22T17:27:44.333 に答える