为什么我的休息声明“太过分”?

时间:2016-02-03 08:56:25

标签: loops powershell break

以下是我的代码片段(基于this previous question):

$rgdNames = (Get-AzureRmResourceGroupDeployment -ResourceGroupName "$azureResGrpName").DeploymentName
$siblings = $rgdNames | Where-Object{$_ -match "^($hostname)(\d+)$" }
if ($siblings) {
    # Make a list of all numbers in the list of hostnames
    $serials = @()
    foreach ($sibling in $siblings) {
        # $sibling -split ($sibling -split '\d+$') < split all digits from end, then strip off everything at the front
        # Then convert it to a number and add that to $serials
        $hostnumber = [convert]::ToInt32([string]$($sibling -split ($sibling -split '\d+$'))[1], 10)
        $serials += $hostnumber
    }
    (1..$siblingsMax) | foreach { # Iterate over all valid serial numbers
        if (!$serials.Contains($_)) { # Stop when we find a serial number that isn't in the list of existing hosts
            $serial = $_
             # break # FIXME: For some reason, this break statement breaks "too far"
        }
    }
} else {
    $serial = 1
}
write-output("serial = $serial") # does not print
# ...more statements here, but they're never called :(

我已经看了一段时间,但无法弄清楚为什么break语句(如果未注释)会停止我的程序而不是仅仅突破其foreach循环。是否有一些我不知道的foreach,或者break的工作方式与Java中的工作方式不同?

目前,我正在使用额外的if测试来解决这个问题,并不意味着(太多)循环运行它的整个长度。但它太丑了!

1 个答案:

答案 0 :(得分:1)

这个结构:

(1..$siblingsMax) | foreach { # Iterate over all valid serial numbers
    # do stuff
}

NOT 一个foreach循环 - 它是一个调用ForEach-Object cmdlet的管道(别名为{{1设计用于中断循环控制流的关键字(如foreachbreak)在这两种不同的情况下不会以相同的方式起作用。

使用正确的continue循环,break将按预期运行:

foreach

或者,您可以滥用continue behaves like you would expect break in a ForEach-Object进程阻止:

这一事实
foreach($i in 1..$siblingsMax){
    # do stuff
    if($shouldBreak)
    {
        break
    }
}

虽然我会强烈阻止这种做法(它只会导致更多的混淆)