2015-06-05 24 views
1

我有一个函数返回全局变量的值。当我将这个结果分配给一个局部变量,并且改变本地值时,另一个变量也在改变。为什么更改本地变量值会影响全局副本

实施例:

function setGlobal 
{ 
    $temp = @{} 

    $temp.id = 50; 

    $Global:global1 = $temp; 

    return $Global:global1; 
} 

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

$result = setGlobal 
$result.id = 80 

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

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

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

+1

本地改变了全局,因为你实际上有两件事情,一个变量和一个变量指向的集合。你没有修改持有集合的变量,你正在修改集合本身.. –

回答

3

的原因是当然,你没有这个对象的两个副本。你有两个对同一个对象的引用,一个散列表。引用被复制,而不是对象。物体就像一座房子。变量(global1和result)就像纸片一样。我在我的一张纸上写下房子的地址(global1),然后将地址复制到您的纸上(结果)。然后你去到你的地址,把门打开。现在当我去到我的地址时,我的房子现在有一扇红色的门。

制作对象的深层副本比复制房屋要容易一些。对于任意对象使用PSObject.Copy()

function setGlobal 
{ 
    $temp = @{} 
    $temp.id = 50; 
    $Global:global1 = $temp; 
    return $Global:global1.PSObject.Copy(); 
} 

在这种情况下,这是完全一样的克隆,因为PSObject.Copy使用克隆(如果可用)。

2

发生这种情况是因为powershell隐式使用引用。因此,当您进行作业时,$Global:global1$result最终指向同一地点。

为了得到一份拷贝,使用.Clone()方法:或

$result = $Global:global1.Clone() 

,而不是这样做的任务,做到这一点的函数的返回:

function setGlobal 
{ 
    $temp = @{} 

    $temp.id = 50; 

    $Global:global1 = $temp; 

    return $Global:global1.Clone(); 
} 
相关问题