4

我正在尝试构建一个函数,该函数本身可以通过 Set-Item 命令创建函数,在该命令中,我将新函数的脚本块传递给 Set-Item 的 -Value 参数。我遇到了一个问题,在脚本块上使用 GetNewClosure 似乎不起作用,我只是不知道我做错了什么。

在下面的代码中,首先我手动创建了一个按预期工作的函数(testFunc),在函数创建后将 $x 设置为 2 不会导致函数返回 2;相反,它返回 1,因为这是创建函数时 $x 的值。但是当我尝试通过 make-function 函数做同样的事情时,行为会发生变化。

我确定我忽略了一些小东西。

> $x = 1
> $block = {$x}.GetNewClosure()
> Set-Item function:global:testFunc -Value $block
> testFunc
1 

> $x = 2
> testFunc
1 # still 1 because of GetNewClosure - this is expected behavior

> $x = 1
> function make-function { $block2 = {$x}.GetNewClosure()
       Set-Item function:global:testFunc2 -Value $block2
  }
> make-function
> testFunc2
1 

> $x = 2
> testFunc2
2 # Why is it not returning 1 in this case? 
4

1 回答 1

6

线索在MSDN 文档中,但很微妙:

调用者上下文中的任何局部变量都将复制到模块中。

GetNewClosure()似乎捕获“仅”局部变量,即来自调用者当前范围的变量。所以试试这个:

function Make-Function {
   $x = $global:x
   $function:global:testFunc2 = {$x}.GetNewClosure()
}

顺便说一句,您可以通过执行以下命令查看哪些变量被捕获GetNewClosure()到新创建的动态模块中:

$m = (Get-Command testFunc2).Module
& $m Get-Variable -Scope 0
于 2014-11-30T23:44:19.757 回答