【问题标题】:Continue while from nested for-loop从嵌套的 for 循环继续 while
【发布时间】:2014-10-16 11:17:34
【问题描述】:

我有以下循环结构:

while ($reader.Read() -eq $true)
{
    $row = @{}
    for ($i = 0; $i -lt $reader.FieldCount; $i++)
    {
        if(something...)
        {
            #continue with while
        }
    }
    #do more stuff...          
}

现在,是否有任何方法可以从 for 循环内部继续进行外部 while 循环的下一次迭代,而无需任何中断变量?所以如果“某事是真的”我不想去#do more stuff,而是去下一个$reader.read()Continue 只进入 for 循环的下一次迭代。 Break 只会破坏for 循环。

【问题讨论】:

    标签: loops powershell


    【解决方案1】:

    将内部循环分解为函数可以提高可读性,具体取决于变量的复杂程度。

    function processRow($reader) {
        $row = @{}
        for ($i = 0; $i -lt $reader.FieldCount; $i++)
        {
            if(-not something...) { return $null }
            # process row
        }
        $row
    }
    
    while ($reader.Read()) {
        $row = processRow $reader
        if ($row) {
            #do more stuff...          
        }
    }
    

    但如果你想直接这样做,你可以,因为 PowerShell 已经标记了中断:

    :nextRow while ($reader.Read()) {
        $row = @{}
        for ($i = 0; $i -lt $reader.FieldCount; $i++) {
            if(something...) {
                #continue with while
                continue nextRow
            }
        }
        #do more stuff...          
    }
    

    【讨论】:

    • 谢谢,那些带标签的休息似乎可以解决问题 - 虽然感觉有点像旧的 GOTO :)
    • 带标签的中断是 Donald Knuth 所说的“结构化GOTO”——您不能将执行转移到任意位置,只能转移到明确定义的位置(即循环的末端)。为了加强这一点,PowerShell 甚至没有 GOTO 语句,这对于脚本语言来说是相当罕见的。
    • 只是一个小编辑:这是continue nextRow not break :nextRow
    • 你说得对——break :nextRow 将从for 内部终止外循环,这不是我们想要的(在这种情况下,它也很有用)。
    • 对我来说 continue nextRow 仅在没有 : 的情况下有效 使用 : 它将继续 for 循环
    【解决方案2】:

    编辑:修改后的递归(且未经测试!)解决方案,因此您的 Millage 可能会有所不同:

    function doReader()
    {
        while ($reader.Read() -eq $true)
        {
            $row = @{}
            for ($i = 0; $i -lt $reader.FieldCount; $i++)
            {
                if(something...)
                {
                    #continue with while
                    doReader
                    break;
                }
            }
        }
    }
    doReader
    #do more stuff
    

    【讨论】:

    • 是的,这就是我所说的“额外的中断变量”。我目前正在使用它,但正在寻找更好的方法;)
    • @silent,试一试编辑后的答案。递归当然更优雅
    • 我不会在脚本语言中使用递归,因为我不希望我未来的维护者理解它——我非常喜欢我未来的维护者。
    猜你喜欢
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多