PowerShell ScriptBlock 不是词汇闭合因为它不会关闭其声明环境中引用的变量。相反,它似乎利用了动态作用域和自由变量,这些变量在运行时绑定在 lambda 表达式中。
function Get-Block {
$b = "PowerShell"
$value = {"Hello $b"}
return $value
}
$block = Get-Block
& $block
# Hello
# PowerShell is not written as it is not defined in the scope
# in which the block was executed.
function foo {
$value = 5
function bar {
return $value
}
return bar
}
foo
# 5
# 5 is written $value existed during the evaluation of the bar function
# it is my understanding that a function is a named scriptblock
# which is also registered to function:
对 ScriptBlock 调用 GetNewClosure() 会返回一个新的 ScriptBlock,该 ScriptBlock 会关闭所引用的变量。但这在范围和能力上都非常有限。
ScriptBlock 的分类是什么?
Per the docs,脚本块是“脚本文本的预编译块”。所以默认情况下你只是一个预先解析的脚本块,不多也不少。执行它会创建一个子作用域,但除此之外,就好像您内联粘贴了代码一样。因此,最合适的术语就是“只读源代码”。
Calling GetNewClosure
固定在动态生成的模块上,该模块基本上携带调用时调用者范围内所有变量的快照GetNewClosure
。它不是真正的闭包,只是变量的快照副本。脚本块本身仍然只是源代码,并且在调用它之前不会发生变量绑定。您可以根据需要在附加模块中添加/删除/编辑变量。
function GetSB
{
$funcVar = 'initial copy'
{"FuncVar is $funcVar"}.GetNewClosure()
$funcVar = 'updated value' # no effect, snapshot is taken when GetNewClosure is called
}
$sb = GetSB
& $sb # FuncVar is initial copy
$funcVar = 'outside'
& $sb # FuncVar is initial copy
$sb.Module.SessionState.PSVariable.Remove('funcVar')
& $sb # FuncVar is outside
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)