PowerShell ScriptBlock不是lexical closure,因为它不会覆盖其声明环境中引用的变量。相反,它似乎利用了在运行时在lambda表达式中绑定(bind)的动态范围和自由变量。
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,脚本块是“脚本文本的预编译块”。因此,默认情况下,您只是预解析的脚本块,不多也不少。执行它会创建一个子作用域,但除此之外,就好像您是内联粘贴代码一样。因此,最合适的术语就是“只读源代码”。
在动态生成的模块上调用GetNewClosure
bolt ,该模块基本上会在调用GetNewClosure
时携带调用方范围内所有变量的快照。它不是真正的闭包,只是变量的快照副本。脚本块本身仍然只是源代码,并且变量绑定(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/