在下面的示例中,Measure-Command变量x更新后,但在示例中我自己的命令版本x保持不变。
$x = 0
Measure-Command -Expression { $x++ } | Out-Null
$x # outputs 1
function Measure-Command2
{
param([ScriptBlock]$Expression)
. $Expression
}
$x = 0
Measure-Command2 -Expression { $x++ }
$x # outputs 0
Run Code Online (Sandbox Code Playgroud)
我可以在自己的函数中使用同样的魔法吗?
最用户友好的解决方案是在动态模块中定义您的函数,使用New-Module:
$null = New-Module {
function Measure-Command2 {
param([ScriptBlock]$Expression)
. $Expression
}
}
$x = 0
Measure-Command2 -Expression { $x++ }
$x # outputs *1* now, as desired.
Run Code Online (Sandbox Code Playgroud)
笔记:
模块在其自己的范围域(也称为会话状态)中运行,与调用者的域不同。因此,与非模块函数不同,在调用时不会创建调用者作用域的子作用域。
作为参数传递的脚本块,由于是{ ... }在调用者的作用域中创建为文字 ( ) 的,因此在调用者的作用域中执行,而不是在函数的作用域中执行。
如果没有模块,您需要对自身的调用进行点源调用,因为函数和脚本默认在子作用域中运行:Measure-Command2
function Measure-Command2 {
param([ScriptBlock]$Expression)
. $Expression
}
$x = 0
# Note the dot-sourcing
. Measure-Command2 -Expression { $x++ }
$x # outputs *1* now, as desired.
Run Code Online (Sandbox Code Playgroud)