为什么“继续”?表现得像“打破”在 Foreach 对象中?
如果我在 PowerShell 脚本中执行以下操作:
$range = 1..100
ForEach ($_ in $range) {
if ($_ % 7 -ne 0 ) { continue; }
Write-Host "$($_) is a multiple of 7"
}
我会得到预期的输出:
7 is a multiple of 7
14 is a multiple of 7
21 is a multiple of 7
28 is a multiple of 7
35 is a multiple of 7
42 is a multiple of 7
49 is a multiple of 7
56 is a multiple of 7
63 is a multiple of 7
70 is a multiple of 7
77 is a multiple of 7
84 is a multiple of 7
91 is a multiple of 7
98 is a multiple of 7
但是,如果我使用管道和 ForEach-Object
,continue
似乎会突破管道循环。
1..100 | ForEach-Object {
if ($_ % 7 -ne 0 ) { continue; }
Write-Host "$($_) is a multiple of 7"
}
我可以在执行 ForEach-Object 的同时获得类似 continue
的行为,这样我就不必破坏我的管道吗?
If I do the following in a PowerShell script:
$range = 1..100
ForEach ($_ in $range) {
if ($_ % 7 -ne 0 ) { continue; }
Write-Host "$($_) is a multiple of 7"
}
I get the expected output of:
7 is a multiple of 7
14 is a multiple of 7
21 is a multiple of 7
28 is a multiple of 7
35 is a multiple of 7
42 is a multiple of 7
49 is a multiple of 7
56 is a multiple of 7
63 is a multiple of 7
70 is a multiple of 7
77 is a multiple of 7
84 is a multiple of 7
91 is a multiple of 7
98 is a multiple of 7
However, if I use a pipeline and ForEach-Object
, continue
seems to break out of the pipeline loop.
1..100 | ForEach-Object {
if ($_ % 7 -ne 0 ) { continue; }
Write-Host "$($_) is a multiple of 7"
}
Can I get a continue
-like behavior while still doing ForEach-Object, so I don't have to breakup my pipeline?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只需使用
返回
而不是继续
即可。此return
从特定迭代中由ForEach-Object
调用的脚本块返回,因此,它模拟循环中的continue
。重构时需要记住一个问题。有时,人们想要使用
ForEach-Object
cmdlet 将foreach
语句块转换为管道(它甚至具有别名foreach
,有助于使这种转换很容易,也很容易出错)。所有继续
都应替换为返回
。PS:不幸的是,在
ForEach-Object
中模拟break
并不是那么容易。Simply use the
return
instead of thecontinue
. Thisreturn
returns from the script block which is invoked byForEach-Object
on a particular iteration, thus, it simulates thecontinue
in a loop.There is a gotcha to be kept in mind when refactoring. Sometimes one wants to convert a
foreach
statement block into a pipeline with aForEach-Object
cmdlet (it even has the aliasforeach
that helps to make this conversion easy and make mistakes easy, too). Allcontinue
s should be replaced withreturn
.P.S.: Unfortunately, it is not that easy to simulate
break
inForEach-Object
.因为
For-Each
对象是一个 cmdlet,而不是循环,并且continue
和break
不适用于它。例如,如果您有:
您将得到如下输出:
这是因为
continue
应用于外部 foreach 循环,而不是 foreach-object cmdlet。如果没有循环,则为最外层,因此给您的印象是它的行为类似于break
。那么如何获得类似
继续
的行为呢?一种方法当然是 Where-Object :Because
For-Each
object is a cmdlet and not a loop andcontinue
andbreak
do not apply to it.For example, if you have:
You will get output as:
It is because the
continue
gets applied to the outer foreach loop and not the foreach-object cmdlet. In absence of a loop, the outermost level, hence giving you an impression of it acting likebreak
.So how do you get a
continue
-like behaviour? One way is Where-Object of course:一个简单的
else
语句使其工作如下:或在单个管道中:
但更优雅的解决方案是反转您的测试并仅为您的成功生成输出
A simple
else
statement makes it work as in:Or in a single pipeline:
But a more elegant solution is to invert your test and generate output for only your successes
另一种选择是一种 hack,但您可以将块包装在一个将执行一次的循环中。这样,
继续
就会达到预期的效果:Another alternative is kind of a hack, but you can wrap your block in a loop that will execute once. That way,
continue
will have the desired effect: