我不太明白这一点,但为什么以下代码不起作用:
"start"
1..5 | foreach {
"$_"
break
}
"stop"
我做了几次测试,这段代码运行正常:
"start"
foreach ($num in 1..5){
"$num"
break
}
"stop"
有没有办法让第一个例子正常运行?最后输出的行应该是“停止”。
像这样:
start
1
stop
答案 0 :(得分:2)
首先,当您使用foreach ($thing in $things) {}
与$things | foreach { }
时,您应该知道使用两种完全不同的语言功能。
第一个是内置的foreach
语句,第二个是ForEach-Object
的别名,它们的工作方式非常不同。
ForEach-Object
为每个项运行脚本块,它在管道中运行。
在这种情况下,break
语句只是break
当前项目的执行。所谓的“父母”不会因为break
而知道脚本块已退出并继续执行下一个对象的脚本块。
如何限制结果取决于你想做什么。
如果您只想停止生成结果,请在条件满足时不要返回任何内容。您仍将运行每次迭代,但结果将是正确的。
如果您只需要返回一定数量的项目,例如第一个N
项目,那么最好的方式(从PowerShell v3开始)就是添加Select-Object
:
1..10 | ForEach-Object {
$_*2
} | Select-Object -First 5
这只会执行5次,它将返回序列2,4,6,8,10
。
这是因为管道在每个对象通过每个cmdlet发送的位置如何工作,而Select-Object
可以停止管道,因此它不会继续执行。
3.0版之前的版本,管道无法以这种方式停止,虽然结果是正确的,但您不会阻止额外的执行。
如果您提供有关退出条件的更多详细信息,我可以提供更多关于您希望如何处理该特定问题的信息(可能涉及不使用ForEach-Object
)。