关于中断
简短说明
描述可用于立即退出 foreach
、、for
、switch
while
do
、 或 trap
语句的语句。
长说明
语句 break
提供了一种退出当前控制块的方法。
在控制块后面的下一个语句处继续执行。 语句支持标签。 标签是分配给脚本中的语句的名称。
使用循环中断
break
当语句出现在循环(如 foreach
、for
、 do
或 while
循环)中时,PowerShell 会立即退出循环。
语句 break
可以包含用于退出嵌入循环的标签。 标签可以在脚本中指定任何循环关键字 (keyword) ,例如 foreach
、 for
或 while
。
以下示例演示如何使用 break
语句退出 for
语句:
for($i=1; $i -le 10; $i++) {
Write-Host $i
break
}
在此示例中, 语句在break
变量等于 1 时$i
退出for
循环。 即使 语句的 for
计算结果为 True ,直到 $i
大于 10,PowerShell 在首次运行循环时 for
会到达 break 语句。
在必须满足内部条件的循环中使用 语句更为常见 break
。 请考虑以下 foreach
语句示例:
$i=0
$varB = 10,20,30,40
foreach ($val in $varB) {
if ($val -eq 30) {
break
}
$i++
}
Write-Host "30 was found in array index $i"
在此示例中, foreach
语句循环访问 $varB
数组。 语句 if
在运行循环的前两次计算结果为 False,变量 $i
递增 1。 第三次运行循环, $i
等于 2, $val
变量等于 30。 此时,语句 break
运行,循环 foreach
退出。
在循环中使用标记的中断
break
语句可以包含标签。 如果将break
关键字 (keyword) 与标签一起使用,PowerShell 会退出标记的循环,而不是退出当前循环。
标签是一个冒号,后跟你分配的名称。 标签必须是 语句中的第一个标记,并且它必须后跟循环关键字 (keyword) ,例如 while
。
break
将执行移出标记的循环。 在嵌入循环中,其结果与break
关键字 (keyword) 本身使用时的结果不同。 此示例有一个 while
语句,其中包含 语句 for
:
:myLabel while (<condition 1>) {
for ($item in $items) {
if (<condition 2>) {
break myLabel
}
$item = $x # A statement inside the For-loop
}
}
$a = $c # A statement after the labeled While-loop
如果条件 2 的计算结果为 True,则脚本的执行将跳到标记循环后的 语句。 在示例中,执行会再次从 语句 $a = $c
开始。
可以嵌套多个标记的循环,如以下示例所示。
:red while (<condition1>) {
:yellow while (<condition2>) {
while (<condition3>) {
if ($a) {break}
if ($b) {break red}
if ($c) {break yellow}
}
Write-Host "After innermost loop"
}
Write-Host "After yellow loop"
}
Write-Host "After red loop"
$b
如果变量的计算结果为 True,则脚本在执行标记为“red”的循环后继续执行。 $c
如果变量的计算结果为 True,则脚本控件的执行将在标记为“黄色”的循环之后恢复。
如果变量 $a
的计算结果为 True,则执行将在最内部的循环之后恢复。 不需要标签。
PowerShell 不限制标签可以恢复执行的时间。 标签甚至可以跨脚本和函数调用边界传递控制。
在 switch 语句中使用 break
在 构造中 switch
, break
导致 PowerShell 退出 switch
代码块。
关键字 (keyword) break
用于离开 switch
构造。 例如,以下 switch
语句使用 break
语句来测试最具体的条件:
$var = "word2"
switch -regex ($var) {
"word2" {
Write-Host "Exact" $_
break
}
"word.*" {
Write-Host "Match on the prefix" $_
break
}
"w.*" {
Write-Host "Match on at least the first letter" $_
break
}
default {
Write-Host "No match" $_
break
}
}
在此示例中, $var
将创建变量并将其初始化为 字符串值 word2
。 语句 switch
使用 Regex 类首先将变量值与术语 word2
匹配。 由于变量值与 语句中的 switch
第一个测试匹配,因此语句中的 switch
第一个代码块将运行。
当 PowerShell 到达第一个 break
语句时,语句 switch
将退出。 如果从示例中删除这四 break
个语句,则满足所有四个条件。 此示例使用 break
语句在满足最具体的条件时显示结果。
在 trap 语句中使用 break
如果在语句正文中执行的最后一个 trap
语句是 break
,则会禁止显示错误对象,并重新引发异常。
以下示例创建使用 trap
语句捕获的 DivideByZeroException 异常。
function test {
trap [DivideByZeroException] {
Write-Host 'divide by zero trapped'
break
}
$i = 3
'Before loop'
while ($true) {
"1 / $i = " + (1 / $i--)
}
'After loop'
}
test
请注意,执行在异常时停止。 After loop
永远不会到达 。
执行 后 trap
会重新引发异常。
Before loop
1 / 3 = 0.333333333333333
1 / 2 = 0.5
1 / 1 = 1
divide by zero trapped
Attempted to divide by zero.
At line:10 char:6
+ "1 / $i = " + (1 / $i--)
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RuntimeException
不要在循环、开关或陷阱之外使用中断
当 break
在直接支持它的构造之外使用 时, (循环、 switch
、 trap
) ,PowerShell 会查找 封闭构造的调用堆栈 。 如果找不到封闭构造,则当前运行空间将静默终止。
这意味着,在支持它的封闭构造之外无意中使用 break
的函数和脚本可能会无意中终止其 调用方。
在 break
管道 break
(如脚本块) ForEach-Object
中使用 不仅会退出管道,还可能会终止整个运行空间。