PowerShell对内部范围使用copy-on-write语义。
这意味着如果您在内部范围内更改外部变量,那么内部范围将处理它自己的副本。这是一个例子:
$list = @(1, 2)
Function Foo
{
"Foo: initial value - $list"
$list = $list + 3
"Foo: `$list: $list, `$global:list: $global:list"
}
输出结果为:
Foo: initial value - 1 2
Foo: $list: 1 2 3, $global:list: 1 2
好的,这种行为是设计的。但是让我们改变Foo
函数:
Function Foo { "Foo: initial value - $list" $list += 3 "Foo: `$list: $list, `$global:list: $global:list" }
输出结果为:
Foo: initial value - 1 2 Foo: $list: 3, $global:list: 1 2
嗯...我可以假设x += y
运算符与x = x + y
不完全相同。但这并没有被解决。让我们再次更改代码:
Function Foo { New-Variable -Name z -Value 42 "Foo: initial value - $list" $list += 3 "Foo: `$list: $list, `$global:list: $global:list" }
现在的输出是:
Foo: initial value - 1 2
Foo: $list: 1 2 3, $global:list: 1 2
这似乎是一个错误。唯一的问题是究竟在哪里?我假设在第二种情况下+=
的行为是不正确的。但也许我错过了一些东西......
答案 0 :(得分:1)
我在PowerShell 2.0中尝试了这3个测试。所有结果都与中的相同
第一次测试。我还尝试了标量值$list = 42
以查看是否有
问题特定于数组。在v2中,所有测试都是相同的(45,45,45),在v3中
他们得到45,3,45。所以问题不仅仅是数组。
然后我看了一下v3.0中的变化,请参阅 WMF 3发行说明.docx 在WMF 3.0。
该文件说:
更改
Read/Modify/Write operators no longer use dynamic scoping for the Read
operation. Also, compound equality operators (including +=, -=, *=, %=, ++,
--) do not use dynamic scoping. The variable is always in the current scope.
样品
$x = 1
& { $x += 1; $x }
# Returns 2 in Windows PowerShell 2.0
# Returns 1 in Windows PowerShell 3.0
错误消息
No error. Results differ.
解决方法
Rewrite to use only the simple assignment operator:
$x = 1
& { $x = $x + 1; $x}
根据该文件,在第3版中,测试2是正确的,测试3显示了错误。
更新:PowerShell 4.0与3.0相同。我没有v5来测试它。