为什么更改局部变量值会影响全局副本

时间:2015-06-05 00:42:56

标签: powershell

我有一个返回全局变量值的函数。当我将此结果分配给局部变量,并更改本地值时,另一个变量也会发生变化。

示例:

function setGlobal
{
    $temp = @{}

    $temp.id = 50;

    $Global:global1 = $temp;

    return $Global:global1;
}

然后我调用此函数,并设置结果值:

$result = setGlobal
$result.id = 80

现在两个变量都具有相同的值。

$Global:global1 # id = 60
$result # id = 60

如何防止这种情况发生?为什么更改本地值会影响全局副本?

2 个答案:

答案 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();
}