我注意到Powershell在本地范围内更改全局变量时管理全局变量的方式存在一些差异。特别是关联数组(哈希(看起来是本机全局的,同时其他变量类型不是全局变量,需要前缀$global:(不仅要读取值,还要更改它(。
这是我的例子:
# global variables test in powershell
$hash = @{}; # associative array
$hash["a"] = "Antenna";
$array = @(); # array
$array += "first";
$count = 1; # numeric
$glob = 1; # numeric
# here we change the values locally
function AddValues() {
$hash["b"] = "Battle";
Write-Host "local array"
$array += "second";
$array # write only "second" so is a local variable
$local = 1;
$local += 1;
Write-Host "local sum result: $local" # here the sum result is 2 ok
Write-Host "count locally: $count" # here the value is 1 ok
$count += 1;
Write-Host "count locally: $count" # here the value is still 1!!!
$count = $count+1;
Write-Host "count locally: $count" # here is 2 !!!
$global:glob += 1;
}
# call the function
AddValues
Write-Host "hash" # here the hash is ok, has 2 values
$hash
Write-Host "array" # here the array has only "first" !!!
$array
Write-Host "count: $count" # here the value is just 1!!!
Write-Host "global: $($global:glob)" # here the value is ok (2)
这是如何解释的?
提前谢谢你
范围规则仅适用于变量!
PowerShell 的默认行为是:
- 您可以透明地读取父作用域中的变量
- 写入变量后,PowerShell 会创建新的本地副本
但是,当您写入哈希表中的特定键时:
$hash["b"] = "value"
。您实际上并没有向名为"hash"的变量写入任何内容 - 该变量仍然包含对完全相同的哈希表的引用(现在恰好有更多的条目(!
另一方面,如果我们实际上为$hash
变量分配了一个新值,您将看到您期望的行为:
function Update-Hash {
$hash = @{"b" = "value"}
$hash
}
$hash = @{"a" = 123}
$hash # shows the a=123 entry
Update-Hash
$hash # still shows a=123 entry, variable is untouched
数组和属性表达式也是如此。
如果要确保获得的变量引用确实是局部的(并且不打算修改父作用域中的对象(,请使用local
作用域修饰符:
function f
{
if($false){
# Oops
$hash = @{}
}
# This will affect any $hash variable in the callers scope
$hash['key'] = 'value'
# This will, appropriately, throw an index exception
$local:hash['key'] = 'value'
}
作为Mathias R. Jessen出色回答的例证:
$hash = @{}; # associative array
$hash["a"] = "Antenna";
$array = @(); # array
$array += "first";
$count = 1000; # numeric
$glob = 2000; # numeric
# here we change the values locally
function AddValues() {
$hash["b"] = "Battle";
$array += "second";
$local = 1;
$local += 1;
$count += 10;
$count = $count+100;
$global:glob += 2;
'---Variables inside function'
foreach ($varia in 'array','count','hash','glob','local') {
foreach ($scope in 'Local','Global','Script',0,1) {
Try {
Get-Variable $varia -scope $scope -ErrorAction Stop |
Select-Object Name, Value, @{Name='Scope';Expression={$scope}}
} catch {}
} }
}
# call the function
AddValues
# How this is explained?
'Variables outside function'
foreach ($varia in 'array','count','hash','glob','local') {
foreach ($scope in 'Local','Global','Script',0,1) {
Try {
Get-Variable $varia -scope $scope -ErrorAction Stop |
Select-Object Name, Value, @{Name='Scope';Expression={$scope}}
} catch {}
} }
输出显示$array局部变量在函数内创建为字符串(此行为与+=
运算符有关,值得更多阐述(:
.SO61888603.ps1
---Variables inside function Name Value Scope ---- ----- ----- array second Local array {first} Global array {first} Script array second 0 array {first} 1 count 110 Local count 1000 Global count 1000 Script count 110 0 count 1000 1 hash {a, b} Global hash {a, b} Script hash {a, b} 1 glob 2002 Global glob 2002 Script glob 2002 1 local 2 Local local 2 0 Variables outside function array {first} Local array {first} Global array {first} Script array {first} 0 count 1000 Local count 1000 Global count 1000 Script count 1000 0 hash {a, b} Local hash {a, b} Global hash {a, b} Script hash {a, b} 0 glob 2002 Local glob 2002 Global glob 2002 Script glob 2002 0