【问题标题】:PowerShell ScriptBlock variable scopePowerShell ScriptBlock 变量范围
【发布时间】:2017-06-20 16:53:17
【问题描述】:

我无法理解ScriptBlocks 中的范围。我指望着某种类似闭包的系统,但我似乎无法让它工作。

我有一个ScriptBlock,它接受一个param 并返回另一个ScriptBlock

$sb1 = {
    Param($Message1);
    Write-Host $Message1;
    {
        Param($Message2);
        Write-Host ($Message1 + " " + $Message2);
    }
}

要获取内部ScriptBlock,我可以使用$sb2 = & $sb1 -Message1 "Message1" 调用$sb1。这与Message1 相呼应,因此我们知道param 已绑定。

现在我可以用& $sb2 -Message2 "Message2" 调用$sb2。我本来期望Message1 Message2,但它只是写Message2

有什么方法可以访问$Message1 变量吗?我不能使用本地或脚本变量,因为内部脚本块的多个实例将具有不同的$Message1s。

这是实际 shell 的实际输出:

PS C:\> $h1 = { Param($Message1); Write-Host $Message1; { Param($Message2); Write-Host ($Message1 + " " + $Message2); } }
PS C:\> $h2 = & $h1 -Message1 "Message1"
Message1
PS C:\> $h2
 Param($Message2); Write-Host ($Message1 + " " + $Message2);
PS C:\> & $h2 -Message2 "Message2"
 Message2

【问题讨论】:

  • 我将用我实际运行的内容更新问题。不过它非常相似。
  • 啊,错过了返回值的赋值。好的,现在说得通了:)

标签: powershell scope closures scriptblock


【解决方案1】:

你需要明确create a closure:

$sb1 = {
    Param($Message1);
    Write-Host $Message1;
    {
        Param($Message2);
        Write-Host ($Message1 + " " + $Message2);
    }.GetNewClosure()
}

然后它对我有用:

PS> $2 = & $sb1 One
One
PS> & $2 Two
One Two

【讨论】:

  • 好的,哇。这完全有道理。我从来不知道 ScriptBlock 实际上有一个 GetNewClosure 方法。大多数语言对闭包并没有那么明确:)
  • 有选择权有时会很好。我编写了脚本,我使用脚本块只是为了访问我知道在那里的变量,并且有一个闭包会很烦人。但是,是的,通常它要么是自动的,要么根本不支持 :-)
  • 也不知道。不错!
  • 我不得不承认,这是我在 PowerShell 中看到的第一个柯里化实例。我从来没有想过这样做:-)
猜你喜欢
  • 1970-01-01
  • 2012-03-08
  • 2015-05-02
  • 2014-09-24
  • 1970-01-01
  • 2015-07-02
  • 2014-09-19
  • 1970-01-01
  • 2014-09-10
相关资源
最近更新 更多