我有一个返回全局变量值的函数。当我将此结果分配给局部变量,并更改本地值时,另一个变量也会发生变化。
示例:
function setGlobal
{
$temp = @{}
$temp.id = 50;
$Global:global1 = $temp;
return $Global:global1;
}
然后我调用此函数,并设置结果值:
$result = setGlobal
$result.id = 80
现在两个变量都具有相同的值。
$Global:global1 # id = 60
$result # id = 60
如何防止这种情况发生?为什么更改本地值会影响全局副本?
答案 0 :(得分:3)
当然,原因是你没有两个副本。您有两个对同一对象的引用,一个哈希表。复制引用,而不是对象。对象就像一座房子。变量(global1和result)就像纸片一样。我在我的纸上写下房子的地址(global1),然后将地址复制到你的纸上(结果)。然后你去你的地址并把门漆成红色。现在当我去我的地址时,我的房子现在有一扇红色的门。
制作一个对象的深层副本比制作一个房子的副本要容易一些。对于任意对象,请使用PSObject.Copy()
:
function setGlobal
{
$temp = @{}
$temp.id = 50;
$Global:global1 = $temp;
return $Global:global1.PSObject.Copy();
}
在这种情况下,这与Clone完全相同,因为PSObject.Copy使用Clone(如果可用)。
答案 1 :(得分:2)
这种情况正在发生,因为powershell隐式使用引用。因此$Global:global1
和$result
在您完成作业时最终会指向相同的位置。
要获取副本,请使用.Clone()
方法:
$result = $Global:global1.Clone()
或者不是在分配时这样做,而是在函数返回时执行:
function setGlobal
{
$temp = @{}
$temp.id = 50;
$Global:global1 = $temp;
return $Global:global1.Clone();
}