& {
$action = & { $y = 100
return { write-host "Value: $y" }.getnewclosure()
}
[void] (register-engineevent -sourcei "foo" -action $action)
[void] (new-event -sourcei "foo")
}
上面的代码打印Value:
,而我希望它打印Value: 100
。这里缺少什么?
答案 0 :(得分:3)
引擎正在调用GetNewClosure()
,这对它来说是一件好事。
当我运行上面的内容时,我得到的输出只有Value:
,但我全局声明$y = 25
并再次运行[void](new-event -sourcei 'foo')
,输出为Value: 25
。然后我再次更改其值$y = 38
,然后再次运行该事件:Value: 38
。
如果你想要的是在创建动作时烘焙$y
的值,那么一种方法是以$y
的值创建脚本块成为文字或文字的一部分:
$action = &{ $y = 100
return (invoke-expression "{write-host 'Value: $y'}")
}
首先解析字符串以插入值,因此Invoke-Expression
最终会执行相应的操作:
{write-host 'Value: 100'}
我不确定除了在字符串中编写scriptblock的整个内容并将其传递给Invoke-Expression
之外,是否还有其他方法可以烘焙该值。
在回复您的评论时,对闭包的进一步解释:
> $action100 = &{$y = 100; return {write-host "Value: $y"}.GetNewClosure()}
> &$action100
Value: 100
这是您期望的结果,这就是您所获得的结果,因为在调用$y
的范围内,脚本块仍然围绕GetNewClosure()
的值“关闭”。
> $y = 25
> &$action100
Value: 100
$y
100
附近仍然关闭。
> $action25 = $action100.GetNewClosure()
> &$action25
Value: 25
这将生成一个新的scriptblock,它包含当前作用域中的变量。它会重新评估该脚本块中$y
的内容,在此上下文中,$y
现在为25。
> $y = 38
> &$action100
Value: 100
> &$action25
Value: 25
> &($action100.GetNewClosure())
Value: 38
此时,由于现在全局声明$y
,当您致电New-Event
时,它会使用GetNewClosure()
并重新评估$y
至38
,并打印Value: 38
。您已获得Value:
,因为在引擎事件调用GetNewClosure()
的上下文中,未定义变量$y
,因此"Value: $y"
变为"Value: "
。