为什么我的break语句会“太远"? [英] Why does my break statement break "too far"?

查看:85
本文介绍了为什么我的break语句会“太远"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码段(基于上一个问题):

Here's a snippet of my code (based on 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中的有所不同?

I have been looking at it for a while, but can't figure out why the break statement (if un-commented) stops my program instead of just breaking out of its foreach loop. Is there something about foreach that I'm not aware of, or does break just work differently than it would in Java?

就目前而言,我正在使用额外的if测试来解决此问题,但这并不意味着循环会遍历整个长度.但这很丑!

For the time being, I'm working around this using an extra if test, and it doesn't mean (too) much that the loop runs its entire length. But it's ugly!

推荐答案

此构造:

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

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

is NOT a foreach loop - it's a pipeline with a call to the ForEach-Object cmdlet (aliased as foreach) - and keywords designed to interrupt the control flow of a loop (like break or continue) will NOT act in the same way in these two different cases.

使用适当的foreach循环,中断将按您预期的方式运行:

Use a proper foreach loop and break will behave as you expect:

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


或者,您可以滥用以下事实: continue的行为就像您在ForEach-Object 流程块中所期望的break:


Alternatively, you can abuse the fact that continue behaves like you would expect break in a ForEach-Object process block:

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

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

although I would strongly discourage this approach (it'll only lead to more confusion)

这篇关于为什么我的break语句会“太远"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆