C# 尾递归调用与迭代(循环)

本文关键字:循环 迭代 尾递归 调用 | 更新日期: 2023-09-27 18:36:03

我正在开发一个扑克应用程序,我几乎已经完成了它,我正在寻找改进,我想知道的一件事是我应该改变我的主要循环方法方法吗?目前它通过使用尾递归调用进行循环。但是,我的朋友建议我将其切换到迭代,因为它使用的是while循环,而循环不需要堆栈空间。这是我现在的代码。

private async Task Turns()
    {
        _turns = ReturnTurns();
        GC.KeepAlive(Updates);
        if (!Player.FoldTurn && Player.Chips > 0)
        {
            if (Player.Turn)
            {
                SetPlayerStuff(true);
                Call -= Player.PreviousCall;
                _up = int.MaxValue;
                _turnCount++;
                Bot1.Turn = true;
                _restart = true;
            }
        }
        if (!Player.Turn)
        {
            await Flip(0);
        }
        if (Player.FoldTurn || !Player.Turn || Player.Chips <= 0)
        {
            Call = TempCall;
            if (StatusLabels[Player.EnumCasted].Contains(RepetitiveVariables.Fold))
            {
                Bot1.Turn = true;
            }
            SetPlayerStuff(false);
            Bot1 = (Bot)await RotateTurns(Bot1, Bot1.EnumCasted);
            Bot2 = (Bot)await RotateTurns(Bot2, Bot2.EnumCasted);
            Bot3 = (Bot)await RotateTurns(Bot3, Bot3.EnumCasted);
            Bot4 = (Bot)await RotateTurns(Bot4, Bot4.EnumCasted);
            Bot5 = (Bot)await RotateTurns(Bot5, Bot5.EnumCasted);
            _restart = false;
        }
        if (!_restart)
        {
            await Turns();
        }
    }

这就是我认为它应该看起来像循环的样子:

    private async Task Turns()
    {
        while (true)
        {
            _turns = ReturnTurns();
            GC.KeepAlive(Updates);
            if (!Player.FoldTurn && Player.Chips > 0)
            {
                if (Player.Turn)
                {
                    SetPlayerStuff(true);
                    Call -= Player.PreviousCall;
                    _up = int.MaxValue;
                    _turnCount++;
                    Bot1.Turn = true;
                    _restart = true;
                }
            }
            if (!Player.Turn)
            {
                await Flip(0);
            }
            if (Player.FoldTurn || !Player.Turn || Player.Chips <= 0)
            {
                Call = TempCall;
                if (StatusLabels[Player.EnumCasted].Contains(RepetitiveVariables.Fold))
                {
                    Bot1.Turn = true;
                }
                SetPlayerStuff(false);
                Bot1 = (Bot) await RotateTurns(Bot1, Bot1.EnumCasted);
                Bot2 = (Bot) await RotateTurns(Bot2, Bot2.EnumCasted);
                Bot3 = (Bot) await RotateTurns(Bot3, Bot3.EnumCasted);
                Bot4 = (Bot) await RotateTurns(Bot4, Bot4.EnumCasted);
                Bot5 = (Bot) await RotateTurns(Bot5, Bot5.EnumCasted);
                _restart = false;
            }
            if (!_restart)
            {
                continue;
            }
            break;
        }
    }

C# 尾递归调用与迭代(循环)

通常,JIT 无法用循环替换递归。这是一个相当深奥的优化方案。

在这里,这甚至没有发挥作用,因为异步方法在内部使用非常不同的调用机制。

此代码将消耗与递归深度成比例的"堆栈空间"。(它不一定是异步方法的堆栈空间。可以是链表形式的堆空间。

从代码质量的角度来看,我发现循环非常可取,因为递归不是大多数人习惯的。在这里,实际上不需要递归的算法。似乎是这项工作的错误工具。我认为您在这里使用递归作为"goto"的替代品,因为所做的只是跳回到方法的开头。

你可以让跳跃条件更干净一点:

        if (!_restart) break;