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/

10-10 02:55