2015-06-05 23 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(); 
} 
相關問題