确认 PowerShell 在阵列上的行为

确认 PowerShell 在阵列上的行为

考虑以下小脚本:

$a = @(1,2,3)#1
$b = $a #2
$a[0] = 101 #3
$b += 99 #4
写主机“a: $a”
写主机“b: $b”

输出是这样的,这需要我思考一下:

答:101 2 3 答案:101 2 3 99

为澄清起见,我的观察如下:

  1. $b 数组在输出中包含四个元素,因此 $b = $a 正在创建一个复制原始数组包含三个项目,然后添加第 99 个元素。如果 $b = $a 是指针操作,那么向 $b 添加一个元素也会影响 $a 数组
  2. 数组包含指向整数的指针,而不是整数本身。事实证明,第 3 行会更改两个数组的内容。如果 $a 包含整数,那么 $b 不会受到影响

我的理解是:

PowerShell 数组始终是指针数组,即使它仅包含整数。将数组分配给另一个变量会创建该指针数组的副本。

正确的?

答案1

我不知道这背后的真正原因,但如果你看看这种行为,你就可以开始理解它:

$a = @(1,2,3)
[int[]]$b = $a
$a[0] = 101
$b += 99

Write-Host $a"`n"
101 2 3

Write-Host $b"`n"
1 2 3 99

您可以看到,它并没有“链接”$b$a,而是将其初始化为一个单独的数组。


进一步阅读值类型 VS 引用类型

http://www.leeholmes.com/blog/2006/09/05/value-types-vs-reference-types/

http://kizan.com/20143263-reference-types-powershell/

答案2

我认为在内部,这些是作为链接列表而不是数组实现的。区别在于它是非常向数组中添加一个项的成本很高,因为数组的大小是声明的,那么连续的为其分配了内存。因此,无法保证下一个连续的内存块可用于数组,并且必须创建一个大小为 (origArray + 1) 的新数组,将旧数组和新元素复制到其中。当然,除了编程经验和观察 powershell 的行为之外,我没有其他证据。

更新

我确实有证据!避免使用列表运算符vs. 如何数组已声明New-Object在 powershell 中。声明数组时请注意 cmdlet 的用户:

PS > $myArray = New-Object string[] 10

因此,您在命令行上与之交互的是两个链接列表。我不确定 Powershell/.NET 如何处理复制链接列表,尽管从您的示例中可以看出,为了提高效率,它只$b保留与相同的指针$a,但是当您将一个项目添加到$b或时$a,它不会显示在另一个中,除非再次明确复制。我喜欢将其称为static copy,但我不知道该术语在该领域是否有用。

相关内容