确认arrays上的PowerShell行为

考虑下面的小脚本:

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

输出是这个需要我想一下:

a:101 2 3 b:101 2 3 99

我的意见澄清:

  1. $ b数组在输出中包含四个元素,所以$ b = $ a正在创build一个包含三个元素的原始数组的副本 ,然后添加99元素。 如果$ b = $ a是一个指针操作,那么向$ b添加一个元素也会影响$ a数组
  2. 该数组包含指向整数的指针,而不是整数本身。 事实certificate第3行改变了两个数组的内容。 如果$ a包含整数,那$ b就不会受到影响

所以我的理解是:

PowerShell数组始终是一个指针数组,即使它只包含整数。 将数组赋值给另一个variables会创build该指针数组的副本。

对?

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

$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 ,而是将它初始化为单独的数组。


进一步阅读值typesVS引用types

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

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

我认为内部这些被实现为链接列表而不是数组。 不同之处在于,向数组中添加一个项目是非常昂贵的,因为声明了一个数组的大小,然后为其分配连续的内存。 因此,不能保证下一个连续的内存块可用于数组,并且必须创build一个新的数组大小(origArray + 1),复制旧数组并复制新元素。 当然,除了编程经验和观察PowerShell的行为,我还没有certificate这一点。

更新

我有证据! 避免列表运算符与在PowerShell中声明数组的方式 在声明数组时,请注意New-Object cmdlet的用户:

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

所以,你在命令行上进行交互的是两个链表。 我不确定Powershell / .NET如何处理复制链表,尽pipe从您的示例中可以看出, $b效率只是与$b保持相同的指针,但是当您将一个项目添加到$b$a ,在另一个显示,除非再次复制。 我喜欢把这个称为static copy ,尽pipe我不知道这个术语在现场是否有用。