为什么继续像在一个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
但是,如果我使用pipe道和ForEach-Object
,继续似乎突破stream水线循环。
1..100 | ForEach-Object { if ($_ % 7 -ne 0 ) { continue; } Write-Host "$($_) is a multiple of 7" }
我的问题是,在继续执行ForEach-Object的过程中,是否可以继续进行类似的行为,所以我不必分裂我的pipe道?
只需使用return
而不是continue
。 这个返回从ForEach-Object
在特定迭代中调用的脚本块返回,因此它模拟循环中的continue
。
1..100 | ForEach-Object { if ($_ % 7 -ne 0 ) { return } Write-Host "$($_) is a multiple of 7" }
这是重构时要牢记的一个问题。 有时候,我们想用一个ForEach-Object
cmdlet将一个foreach
语句块转换成一个pipe道(它甚至有别名foreach
,这使得这个转换变得简单,而且容易出错)。 所有的continue
应该被replace为return
。
PS不幸的是,在ForEach-Object
模拟break
并不容易。
因为For-Each
对象是一个cmdlet而不是一个循环,continue / break不适用于它。
例如,如果您有:
$b = 1,2,3 foreach($a in $b){ $a | foreach { if($_ -eq 2) {continue;} else {write-host $_} } write-host "after" }
你会得到如下输出:
1 after 3 after
这是因为continue会应用到外部foreach循环而不是foreach-object cmdlet。 没有一个循环,最外层的水平,因此给你一个印象,就像打破。
那么,你如何继续像行为? 其中一种方式就是在哪里 –
1..100 | ?{ $_ % 7 -eq 0} | %{write-host $_ is a mutliple of 7}
另一种方法是黑客攻击,但是你可以把你的代码块放在一个循环中执行一次,这样就可以继续执行预期的效果:
1..100 | ForEach-Object { for($cont=$true;$cont;$cont=$false){ if ($_ % 7 -ne 0 ) { continue; } Write-Host "$($_) is a multiple of 7" } }