为什么我的 break 语句会中断 "too far"?
Why does my break statement break "too far"?
这是我的代码片段(基于 ):
$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..$siblingsMax) | foreach { # Iterate over all valid serial numbers
# do stuff
}
是 不是 一个 foreach
循环 - 它是一个调用 ForEach-Object
cmdlet (别名为 foreach
) - 设计用于中断循环控制流的关键字(如 break
或 continue
)在这两种不同的情况下不会以相同的方式起作用。
使用适当的 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
}
}
虽然我强烈不鼓励这种方法(它只会导致更多的混乱)
这是我的代码片段(基于
$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..$siblingsMax) | foreach { # Iterate over all valid serial numbers
# do stuff
}
是 不是 一个 foreach
循环 - 它是一个调用 ForEach-Object
cmdlet (别名为 foreach
) - 设计用于中断循环控制流的关键字(如 break
或 continue
)在这两种不同的情况下不会以相同的方式起作用。
使用适当的 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
}
}
虽然我强烈不鼓励这种方法(它只会导致更多的混乱)