【问题标题】:Why does my break statement break "too far"?为什么我的 break 语句打破“太远”?
【发布时间】:2016-05-12 09:01:03
【问题描述】:

这是我的代码的 sn-p(基于 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 测试来解决这个问题,这并不意味着(太多)循环运行其整个长度。但是很丑!

【问题讨论】:

  • 呃,不,我没有,但是在将代码粘贴到这篇文章后,我犯了格式错误。抱歉,感谢您接听。

标签: loops powershell break


【解决方案1】:

这个结构:

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

不是一个foreach循环 - 它是一个调用ForEach-Object cmdlet(别名为foreach)的管道 - 以及旨在中断的关键字在这两种不同的情况下,循环的控制流(如 breakcontinue)不会以相同的方式运行。

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

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

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

(1..$siblingsMax) | foreach { # Iterate over all valid serial numbers
    if($shouldBreak)
    {
        continue
    }
}

虽然我会强烈不鼓励这种方法(它只会导致更多的混乱)

【讨论】:

  • 感谢您在 foreach 上教育我。我已将循环改写为您的公式。然而,事情仍然以同样的方式运作...... :(
  • 这很奇怪。您能否在您的问题中添加“改写”版本?
  • AFAIK,在没有循环的情况下,continue 的行为完全符合break:它会在提示中返回您。我认为,这不是 OP 想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
相关资源
最近更新 更多