PowerShell ScriptBlock 不是 lexical closure因为它不会关闭在其声明环境中引用的变量。相反,它似乎利用了在运行时绑定(bind)在 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 的分类是什么?
最佳答案
根据 the docs ,脚本 block 是“脚本文本的预编译 block ”。因此,默认情况下,您只是一个预解析的脚本 block ,不多也不少。执行它会创建一个子范围,但除此之外,就好像您粘贴了内联代码。所以最合适的术语就是“只读源代码”。
调用GetNewClosure
固定在动态生成的模块上,该模块基本上包含调用者范围内所有变量的快照 GetNewClosure
.它不是真正的闭包,只是变量的快照副本。脚本 block 本身仍然只是源代码,在调用它之前不会发生变量绑定(bind)。您可以根据需要在附加的模块中添加/删除/编辑变量。
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
关于function - 什么是 PowerShell ScriptBlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12574146/