检查函数是否在递归函数调用中

3

在Powershell中,函数是否能够知道自身是否被调用?

是否可能通过反射技术来得知当前函数嵌套的深度?还是需要通过设置标志等手段自己完成?


你想要实现什么目标?我怀疑这不是正确的方法。 - Martin Brandl
1个回答

9

使用Get-PSCallStack(自3.0版本引入)命令,您可以通过将调用堆栈中的最后一个条目与当前命令名称进行比较来构建一个简单的“递归检查”。

if((Get-PSCallStack)[1].Command -eq $MyInvocation.MyCommand)
{
    Write-Warning "Function was likely called by itself"
}

当前函数嵌套了多少层,有没有办法知道?

是的,你可以遍历调用堆栈并计算当前函数之前有多少个嵌套调用(随着递归深入会变得非常慢)。

考虑以下示例:

function Invoke-Recurse
{
    param(
        [Parameter()]
        [ValidateRange(0,10)]
        [int]$Depth = 5
    )

    $CallStack = @(Get-PSCallStack)
    $Caller    = $CallStack[1].Command
    $Self      = $CallStack[0].Command

    if($Caller -eq $Self)
    {
        for($i = 1; $i -lt $CallStack.Count; $i++)
        {
            if($CallStack[$i].Command -ne $Self)
            {
                $RecursionLevel = $i - 1
                break
            }
        }
        Write-Warning "Recursion detected! Current depth: $RecursionLevel; Remaining iterations: $Depth"
    }

    if($Depth -lt 1)
    {
        return $true
    }
    else
    {
        return Invoke-Recurse -Depth $($Depth - 1)
    }
}

并且你会看到:

PS C:\> Invoke-Recurse
WARNING: Recursion detected! Current depth: 1; Remaining iterations: 4
WARNING: Recursion detected! Current depth: 2; Remaining iterations: 3
WARNING: Recursion detected! Current depth: 3; Remaining iterations: 2
WARNING: Recursion detected! Current depth: 4; Remaining iterations: 1
WARNING: Recursion detected! Current depth: 5; Remaining iterations: 0
Done!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接