如何一劳永逸地摆脱循环?

时间:2016-05-04 23:24:01

标签: powershell

我有这个文件:

function t {
    "abcd" -split "" |%{ if ($_ -eq "b") { return; } write-host $_; }
}
$o = @{}
$o |add-member -name t -membertype scriptmethod -value {
    "abcd" -split "" |%{ if ($_ -eq "b") { return; } write-host $_; }
}

write-host '-function-'
t;
write-host '-method-'
$o.t();

如果我运行它,我会得到:

-function-
a
c
d
-method-
a
c
d

正如所料。但如果我想要的是' a',我可以用return替换break。如果我在函数中这样做,我得到的是:

-function-
a

因此该方法甚至不会被调用。如果我在方法中替换它,它就不会编译(并抱怨调用它)。这是怎么回事?

以及一次又一次退出foreach-object循环的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

最简单的解决方案是将其重写为foreach语句,而不是使用ForEach-Object命令,这很难停止:

$o | add-member -name t -membertype scriptmethod -value {
    foreach($e in "abcd" -split "") {
        if ($_ -eq "b") { break }
        write-host $_; 
    }
}

作为旁注,foreach(){}关键字/构造比ForEach-Object的管道运行速度快得多。

为了完整起见......

要停止管道,请抛出PipelineStoppedException

"abcd" -split "" | % {
    if($_ -eq "b") {
      throw [System.Management.Automation.PipelineStoppedException]::new() 
    }
    $_ 
}

答案 1 :(得分:0)

您不使用return来停止ForEach,而是使用var hardhttps=require('hardhttps'); hardhttps.globalAgent.options.ca=require('ssl-root-cas/latest').inject().addFile('/etc/letsencrypt/lets-encrypt-x3-cross-signed.pem'); var pem={ key:require('fs').readFileSync('/etc/letsencrypt/live/mysite.com/privkey.pem','utf8') , cert:require('fs').readFileSync('/etc/letsencrypt/live/mysite.com/fullchain.pem','utf8') , ca:require('fs').readFileSync('/etc/letsencrypt/lets-encrypt-x3-cross-signed.pem','utf8') , pass:'xxxx' } var server=(hardhttps.createServer({key:pem.key,cert:pem.cert,ca:[pem.ca],passphrase:pem.pass})).listen(port); var wss=new WebSocketServer({server:server}); ,因为它在对象的每个成员上都作为lambda执行。