通过引用传递 Powershell 数组未按预期工作
Passing Powershell Arrays by-reference not working as intended
引用数组
工作正常!
在 PowerShell 中通过引用传递数组的正常方法似乎工作正常:
Function Swap-Array ($theArray, $theArrayB, [int]$indexToSwap) {
$temp = $theArrayA[$indexToSwap];
$theArrayA[$indexToSwap] = $theArrayB[$indexToSwap];
$theArrayB[$indexToSwap] = $temp;
}
$a = @(1,2,3,4)
$b = @(3,2,4,1)
$a
$b
Swap-Array $a, $b, 2
$a
$b
输出:
a
-
1
2
3
4
b
-
3
2
4
1
a
-
1
2
4
3
b
-
3
2
3
1
问题
添加对象
当引用数组是一个非静态的 PSObjects 容器时,问题就出现了,而我正在尝试添加一条新记录。修改已有的记录好像没问题!
Function Swap-Apples($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Apples;
$objectA[$indexToSwap].Apples = $objectB[$indexToSwap].Apples;
$objectB[$indexToSwap].Apples = $temp;
}
Function Swap-Oranges($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Oranges;
$objectA[$indexToSwap].Oranges = $objectB[$indexToSwap].Oranges;
$objectB[$indexToSwap].Oranges = $temp;
}
<# heres the problematic bit #>
Function Add-Fruit ($object, [int]$howManyApples, [int]$howManyOranges) {
$hAdd = @{
Apples=$howManyApples
Oranges=$howManyOranges
}
$hToAdd = New-Object -TypeName PSObject -Property $hAdd;
$object += $hToAdd;
}
$a = @();
$b = @();
$a1 = @{
Apples=3
Oranges=2
}
$b1 = @{
Apples=5
Oranges=7
}
$a2 = @{
Apples=6
Oranges=3
}
$b2 = @{
Apples=1
Oranges=5
}
$aObject1 = New-Object -TypeName PSObject -Property $a1;
$bObject1 = New-Object -TypeName PSObject -Property $b1;
$aObject2 = New-Object -TypeName PSObject -Property $a2;
$bObject2 = New-Object -TypeName PSObject -Property $b2;
$a += $aObject1; $a += $aObject2;
$b += $bObject1; $b += $aObject2;
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Now lets make a trade`!";
Swap-Apples $a $b 0
Swap-Oranges $a $b 1
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Hey, I brought more fruit for A`!";
Add-Fruit -object $a -howManyApples 5 -howManyOranges 2
Write-Host "Values of A";
$a | Format-List
Write-Host "I brought more fruit for B too`!";
Add-Fruit -object $b -howManyApples 5 -howManyOranges 3
Write-Host "Values of B";
$b | Format-List
输出
Values of A
Oranges : 2
Apples : 3
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 5
Oranges : 3
Apples : 6
Now lets make a trade!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Hey, I brought more fruit for A!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
I brought more fruit for B too!
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Swap-Apples
和 Swap-Oranges
函数似乎工作正常。程序在最后一段崩溃了,试图给A和B更多的水果!否则这通常会在本地范围内工作。我觉得这是由于引用传递而崩溃的。
我将如何着手解决这个程序结束时的问题?
解决方案
动态数组列表
在 PowerShell 中,您可以创建 fixed-size 和动态分配的数组。如果我想给 A 和 B 更多对象,我必须告诉 PowerShell 这是一个 ArrayList 而不是典型的标准数组。
这意味着我不能这样声明我的数组:
$a = @();
$b = @();
这种类型在 .NET 中称为 System.Collections.ArrayList
,可以在 PowerShell 程序中传递 by-reference,如下所示:
$a = New-Object -TypeName 'System.Collections.ArrayList';
$b = New-Object -TypeName 'System.Collections.ArrayList';
现在不是 fixed-size,因此我可以随意在程序中的任何位置添加记录,甚至可以通过引用添加记录!
解决方法如下:
Function Swap-Apples($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Apples;
$objectA[$indexToSwap].Apples = $objectB[$indexToSwap].Apples;
$objectB[$indexToSwap].Apples = $temp;
}
Function Swap-Oranges($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Oranges;
$objectA[$indexToSwap].Oranges = $objectB[$indexToSwap].Oranges;
$objectB[$indexToSwap].Oranges = $temp;
}
<# ArrayList! #>
Function Add-Fruit ([System.Collections.ArrayList]$object, [int]$howManyApples, [int]$howManyOranges) {
$hAdd = @{
Apples=$howManyApples
Oranges=$howManyOranges
}
$hToAdd = New-Object -TypeName PSObject -Property $hAdd;
<# We have to call the ArrayList Add method to add to our dynamic object #>
$object.Add($hToAdd);
}
$a = New-Object -TypeName 'System.Collections.ArrayList';
$b = New-Object -TypeName 'System.Collections.ArrayList';
$a1 = @{
Apples=3
Oranges=2
}
$b1 = @{
Apples=5
Oranges=7
}
$a2 = @{
Apples=6
Oranges=3
}
$b2 = @{
Apples=1
Oranges=5
}
$aObject1 = New-Object -TypeName PSObject -Property $a1;
$bObject1 = New-Object -TypeName PSObject -Property $b1;
$aObject2 = New-Object -TypeName PSObject -Property $a2;
$bObject2 = New-Object -TypeName PSObject -Property $b2;
<# Here we call the ArrayList Add method #>
$a.Add($aObject1); $a.Add($aObject2);
$b.Add($bObject1); $b.Add($aObject2);
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Now lets make a trade`!";
Swap-Apples $a $b 0
Swap-Oranges $a $b 1
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Hey, I brought more fruit for A`!";
Add-Fruit -object $a -howManyApples 5 -howManyOranges 2
Write-Host "Values of A";
$a | Format-List
Write-Host "I brought more fruit for B too`!";
Add-Fruit -object $b -howManyApples 5 -howManyOranges 3
Write-Host "Values of B";
$b | Format-List
以及(某种程度上)预期的输出(见下文):
0
1
0
1
Values of A
Oranges : 2
Apples : 3
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 5
Oranges : 3
Apples : 6
Now lets make a trade!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Hey, I brought more fruit for A!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Oranges : 2
Apples : 5
I brought more fruit for B too!
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Oranges : 3
Apples : 5
额外输出 ?
如果您在输出中观察到:
0
1
0
1
ArrayList的添加方法returns您添加的记录的索引。因为它 returns 这个值会从你的管道中掉落到 Std-Out,所以确保你相应地引导它。
如果您的程序中不需要此输出(就像我在这里不需要的那样),请将其通过管道传输到空设备,如下所示:
$a.Add($aObject1) | Out-Null; $a.Add($aObject2) | Out-Null;
$b.Add($bObject1) | Out-Null; $b.Add($aObject2) | Out-Null;
这是最后的 program/output:
代码:(Arraytest.ps1)
Function Swap-Apples($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Apples;
$objectA[$indexToSwap].Apples = $objectB[$indexToSwap].Apples;
$objectB[$indexToSwap].Apples = $temp;
}
Function Swap-Oranges($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Oranges;
$objectA[$indexToSwap].Oranges = $objectB[$indexToSwap].Oranges;
$objectB[$indexToSwap].Oranges = $temp;
}
<# ArrayList! #>
Function Add-Fruit ([System.Collections.ArrayList]$object, [int]$howManyApples, [int]$howManyOranges) {
$hAdd = @{
Apples=$howManyApples
Oranges=$howManyOranges
}
$hToAdd = New-Object -TypeName PSObject -Property $hAdd;
<# We have to call the ArrayList Add method to add to our dynamic object #>
$object.Add($hToAdd) | Out-Null;
}
$a = New-Object -TypeName 'System.Collections.ArrayList';
$b = New-Object -TypeName 'System.Collections.ArrayList';
$a1 = @{
Apples=3
Oranges=2
}
$b1 = @{
Apples=5
Oranges=7
}
$a2 = @{
Apples=6
Oranges=3
}
$b2 = @{
Apples=1
Oranges=5
}
$aObject1 = New-Object -TypeName PSObject -Property $a1;
$bObject1 = New-Object -TypeName PSObject -Property $b1;
$aObject2 = New-Object -TypeName PSObject -Property $a2;
$bObject2 = New-Object -TypeName PSObject -Property $b2;
<# Here we call the ArrayList Add method #>
$a.Add($aObject1) | Out-Null; $a.Add($aObject2) | Out-Null;
$b.Add($bObject1) | Out-Null; $b.Add($aObject2) | Out-Null;
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Now lets make a trade`!";
Swap-Apples $a $b 0
Swap-Oranges $a $b 1
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Hey, I brought more fruit for A`!";
Add-Fruit -object $a -howManyApples 5 -howManyOranges 2
Write-Host "Values of A";
$a | Format-List
Write-Host "I brought more fruit for B too`!";
Add-Fruit -object $b -howManyApples 5 -howManyOranges 3
Write-Host "Values of B";
$b | Format-List
输出:
Values of A
Oranges : 2
Apples : 3
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 5
Oranges : 3
Apples : 6
Now lets make a trade!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Hey, I brought more fruit for A!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Oranges : 2
Apples : 5
I brought more fruit for B too!
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Oranges : 3
Apples : 5
对我有用:
Function Swap-Array ($theArrayA, $theArrayB, [int]$indexToSwap)
{
$temp = $theArrayA[$indexToSwap]
$theArrayA[$indexToSwap] = $theArrayB[$indexToSwap]
$theArrayB[$indexToSwap] = $temp
}
$a = @(1,2,3,4)
$b = @(3,2,4,1)
$a
$b
Swap-Array $a $b 2
$a
$b
去掉逗号即可。
引用数组
工作正常!
在 PowerShell 中通过引用传递数组的正常方法似乎工作正常:
Function Swap-Array ($theArray, $theArrayB, [int]$indexToSwap) {
$temp = $theArrayA[$indexToSwap];
$theArrayA[$indexToSwap] = $theArrayB[$indexToSwap];
$theArrayB[$indexToSwap] = $temp;
}
$a = @(1,2,3,4)
$b = @(3,2,4,1)
$a
$b
Swap-Array $a, $b, 2
$a
$b
输出:
a
-
1
2
3
4
b
-
3
2
4
1
a
-
1
2
4
3
b
-
3
2
3
1
问题
添加对象
当引用数组是一个非静态的 PSObjects 容器时,问题就出现了,而我正在尝试添加一条新记录。修改已有的记录好像没问题!
Function Swap-Apples($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Apples;
$objectA[$indexToSwap].Apples = $objectB[$indexToSwap].Apples;
$objectB[$indexToSwap].Apples = $temp;
}
Function Swap-Oranges($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Oranges;
$objectA[$indexToSwap].Oranges = $objectB[$indexToSwap].Oranges;
$objectB[$indexToSwap].Oranges = $temp;
}
<# heres the problematic bit #>
Function Add-Fruit ($object, [int]$howManyApples, [int]$howManyOranges) {
$hAdd = @{
Apples=$howManyApples
Oranges=$howManyOranges
}
$hToAdd = New-Object -TypeName PSObject -Property $hAdd;
$object += $hToAdd;
}
$a = @();
$b = @();
$a1 = @{
Apples=3
Oranges=2
}
$b1 = @{
Apples=5
Oranges=7
}
$a2 = @{
Apples=6
Oranges=3
}
$b2 = @{
Apples=1
Oranges=5
}
$aObject1 = New-Object -TypeName PSObject -Property $a1;
$bObject1 = New-Object -TypeName PSObject -Property $b1;
$aObject2 = New-Object -TypeName PSObject -Property $a2;
$bObject2 = New-Object -TypeName PSObject -Property $b2;
$a += $aObject1; $a += $aObject2;
$b += $bObject1; $b += $aObject2;
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Now lets make a trade`!";
Swap-Apples $a $b 0
Swap-Oranges $a $b 1
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Hey, I brought more fruit for A`!";
Add-Fruit -object $a -howManyApples 5 -howManyOranges 2
Write-Host "Values of A";
$a | Format-List
Write-Host "I brought more fruit for B too`!";
Add-Fruit -object $b -howManyApples 5 -howManyOranges 3
Write-Host "Values of B";
$b | Format-List
输出
Values of A
Oranges : 2
Apples : 3
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 5
Oranges : 3
Apples : 6
Now lets make a trade!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Hey, I brought more fruit for A!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
I brought more fruit for B too!
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Swap-Apples
和 Swap-Oranges
函数似乎工作正常。程序在最后一段崩溃了,试图给A和B更多的水果!否则这通常会在本地范围内工作。我觉得这是由于引用传递而崩溃的。
我将如何着手解决这个程序结束时的问题?
解决方案
动态数组列表
在 PowerShell 中,您可以创建 fixed-size 和动态分配的数组。如果我想给 A 和 B 更多对象,我必须告诉 PowerShell 这是一个 ArrayList 而不是典型的标准数组。
这意味着我不能这样声明我的数组:
$a = @();
$b = @();
这种类型在 .NET 中称为 System.Collections.ArrayList
,可以在 PowerShell 程序中传递 by-reference,如下所示:
$a = New-Object -TypeName 'System.Collections.ArrayList';
$b = New-Object -TypeName 'System.Collections.ArrayList';
现在不是 fixed-size,因此我可以随意在程序中的任何位置添加记录,甚至可以通过引用添加记录!
解决方法如下:
Function Swap-Apples($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Apples;
$objectA[$indexToSwap].Apples = $objectB[$indexToSwap].Apples;
$objectB[$indexToSwap].Apples = $temp;
}
Function Swap-Oranges($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Oranges;
$objectA[$indexToSwap].Oranges = $objectB[$indexToSwap].Oranges;
$objectB[$indexToSwap].Oranges = $temp;
}
<# ArrayList! #>
Function Add-Fruit ([System.Collections.ArrayList]$object, [int]$howManyApples, [int]$howManyOranges) {
$hAdd = @{
Apples=$howManyApples
Oranges=$howManyOranges
}
$hToAdd = New-Object -TypeName PSObject -Property $hAdd;
<# We have to call the ArrayList Add method to add to our dynamic object #>
$object.Add($hToAdd);
}
$a = New-Object -TypeName 'System.Collections.ArrayList';
$b = New-Object -TypeName 'System.Collections.ArrayList';
$a1 = @{
Apples=3
Oranges=2
}
$b1 = @{
Apples=5
Oranges=7
}
$a2 = @{
Apples=6
Oranges=3
}
$b2 = @{
Apples=1
Oranges=5
}
$aObject1 = New-Object -TypeName PSObject -Property $a1;
$bObject1 = New-Object -TypeName PSObject -Property $b1;
$aObject2 = New-Object -TypeName PSObject -Property $a2;
$bObject2 = New-Object -TypeName PSObject -Property $b2;
<# Here we call the ArrayList Add method #>
$a.Add($aObject1); $a.Add($aObject2);
$b.Add($bObject1); $b.Add($aObject2);
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Now lets make a trade`!";
Swap-Apples $a $b 0
Swap-Oranges $a $b 1
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Hey, I brought more fruit for A`!";
Add-Fruit -object $a -howManyApples 5 -howManyOranges 2
Write-Host "Values of A";
$a | Format-List
Write-Host "I brought more fruit for B too`!";
Add-Fruit -object $b -howManyApples 5 -howManyOranges 3
Write-Host "Values of B";
$b | Format-List
以及(某种程度上)预期的输出(见下文):
0
1
0
1
Values of A
Oranges : 2
Apples : 3
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 5
Oranges : 3
Apples : 6
Now lets make a trade!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Hey, I brought more fruit for A!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Oranges : 2
Apples : 5
I brought more fruit for B too!
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Oranges : 3
Apples : 5
额外输出 ?
如果您在输出中观察到:
0
1
0
1
ArrayList的添加方法returns您添加的记录的索引。因为它 returns 这个值会从你的管道中掉落到 Std-Out,所以确保你相应地引导它。
如果您的程序中不需要此输出(就像我在这里不需要的那样),请将其通过管道传输到空设备,如下所示:
$a.Add($aObject1) | Out-Null; $a.Add($aObject2) | Out-Null;
$b.Add($bObject1) | Out-Null; $b.Add($aObject2) | Out-Null;
这是最后的 program/output:
代码:(Arraytest.ps1)
Function Swap-Apples($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Apples;
$objectA[$indexToSwap].Apples = $objectB[$indexToSwap].Apples;
$objectB[$indexToSwap].Apples = $temp;
}
Function Swap-Oranges($objectA, $objectB, $indexToSwap) {
$temp = $objectA[$indexToSwap].Oranges;
$objectA[$indexToSwap].Oranges = $objectB[$indexToSwap].Oranges;
$objectB[$indexToSwap].Oranges = $temp;
}
<# ArrayList! #>
Function Add-Fruit ([System.Collections.ArrayList]$object, [int]$howManyApples, [int]$howManyOranges) {
$hAdd = @{
Apples=$howManyApples
Oranges=$howManyOranges
}
$hToAdd = New-Object -TypeName PSObject -Property $hAdd;
<# We have to call the ArrayList Add method to add to our dynamic object #>
$object.Add($hToAdd) | Out-Null;
}
$a = New-Object -TypeName 'System.Collections.ArrayList';
$b = New-Object -TypeName 'System.Collections.ArrayList';
$a1 = @{
Apples=3
Oranges=2
}
$b1 = @{
Apples=5
Oranges=7
}
$a2 = @{
Apples=6
Oranges=3
}
$b2 = @{
Apples=1
Oranges=5
}
$aObject1 = New-Object -TypeName PSObject -Property $a1;
$bObject1 = New-Object -TypeName PSObject -Property $b1;
$aObject2 = New-Object -TypeName PSObject -Property $a2;
$bObject2 = New-Object -TypeName PSObject -Property $b2;
<# Here we call the ArrayList Add method #>
$a.Add($aObject1) | Out-Null; $a.Add($aObject2) | Out-Null;
$b.Add($bObject1) | Out-Null; $b.Add($aObject2) | Out-Null;
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Now lets make a trade`!";
Swap-Apples $a $b 0
Swap-Oranges $a $b 1
Write-Host "Values of A";
$a | Format-List
Write-Host "Values of B";
$b | Format-List
Write-Host "Hey, I brought more fruit for A`!";
Add-Fruit -object $a -howManyApples 5 -howManyOranges 2
Write-Host "Values of A";
$a | Format-List
Write-Host "I brought more fruit for B too`!";
Add-Fruit -object $b -howManyApples 5 -howManyOranges 3
Write-Host "Values of B";
$b | Format-List
输出:
Values of A
Oranges : 2
Apples : 3
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 5
Oranges : 3
Apples : 6
Now lets make a trade!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Hey, I brought more fruit for A!
Values of A
Oranges : 2
Apples : 5
Oranges : 3
Apples : 6
Oranges : 2
Apples : 5
I brought more fruit for B too!
Values of B
Oranges : 7
Apples : 3
Oranges : 3
Apples : 6
Oranges : 3
Apples : 5
对我有用:
Function Swap-Array ($theArrayA, $theArrayB, [int]$indexToSwap)
{
$temp = $theArrayA[$indexToSwap]
$theArrayA[$indexToSwap] = $theArrayB[$indexToSwap]
$theArrayB[$indexToSwap] = $temp
}
$a = @(1,2,3,4)
$b = @(3,2,4,1)
$a
$b
Swap-Array $a $b 2
$a
$b
去掉逗号即可。