2017-06-08 2 views
5

Ich verwende Powershell 2.0. Wenn ich eine neue Variable als ein Array mache und dann eine andere Variable gleich der ersten setze, "spiegelt" die zweite Variable die erste Variable. Nach dem Ändern eines Objekts im ursprünglichen Array wird die genau gleiche Änderung im zweiten Array angezeigt. Zum BeispielWarum spiegeln sich einige Arrays in Powershell gegenseitig?

$array0001=6,7,3,4,0 
$array0002=$array0001 
$array0001[3]=55 
$array0002 

mit dem auszugebende

6 
7 
3 
55 
0 

ich feststellen, dass, wenn man die zweite Variable den gleichen Wert wie die erste Variable haben, außer dieser Zeit innerhalb eines subexpression Bediener eingeschlossen, Modifikationen auf das erste Array haben keinen Einfluss auf das zweite Array. Zum Beispiel

$array0001=6,7,3,4,0 
$array0002=$($array0001) 
$array0001[3]=55 
$array0002 

mit dem Ausgang das Verhalten der Variablen in einer subexpression Operator Änderung

seine
6 
7 
3 
4 
0 

Warum den Wert nicht umschließt? Gibt es einen anderen oder besseren Weg, Array-Variablen zu vermeiden, die sich gegenseitig "spiegeln"?

ETA: Ich habe jetzt gefunden, dass [email protected]($array0001) und $array0002=&{$array0001} beide genau das gleiche Ziel erreichen.

Antwort

7

Es heißt "pass by reference". Anstatt einen Wert tatsächlich zuzuweisen, weisen Sie einen Verweis auf einen anderen Speicherort zu, der einen Wert enthält. Wenn sich der Wert am ursprünglichen Speicherort ändert, verweist der von Ihnen erstellte Verweis auf den ursprünglichen Speicherort und zeigt den aktualisierten Wert an.

In den meisten Sprachen gibt es Möglichkeiten, "durch Referenz" und "nach Wert" zu übergeben. Das haben Sie gefunden, indem Sie $array0002=$($array0001) getan haben. Keiner ist besser als der andere, beide haben unterschiedliche Nutzungen.

In PowerShell können Sie auch .value hinter Ihre Referenz setzen, um den Wert anstelle der Referenz zu erfassen.

2

Wenn ein Array einem anderen gleichgesetzt wird, verweisen die verschiedenen Variablen einfach aufeinander, es ist keine echte Kopie. This ist im Wesentlichen das gleiche, was Sie fragen. Von diesem Link aus ist das Serialisieren der Daten für eine tiefe Kopie ein guter Weg.

#Original data 
$Array1 

# Serialize and Deserialize data using BinaryFormatter 
$ms = New-Object System.IO.MemoryStream 
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter 
$bf.Serialize($ms, $Array1) 
$ms.Position = 0 

#Deep copied data 
$Array2 = $bf.Deserialize($ms) 
$ms.Close() 
Verwandte Themen