考虑以下小脚本:
$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
为澄清起见,我的观察如下:
- $b 数组在输出中包含四个元素,因此 $b = $a 正在创建一个复制原始数组包含三个项目,然后添加第 99 个元素。如果 $b = $a 是指针操作,那么向 $b 添加一个元素也会影响 $a 数组
- 数组包含指向整数的指针,而不是整数本身。事实证明,第 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/
答案2
我认为在内部,这些是作为链接列表而不是数组实现的。区别在于它是非常向数组中添加一个项的成本很高,因为数组的大小是声明的,那么连续的为其分配了内存。因此,无法保证下一个连续的内存块可用于数组,并且必须创建一个大小为 (origArray + 1) 的新数组,将旧数组和新元素复制到其中。当然,除了编程经验和观察 powershell 的行为之外,我没有其他证据。
更新
我确实有证据!避免使用列表运算符vs. 如何数组已声明New-Object
在 powershell 中。声明数组时请注意 cmdlet 的用户:
PS > $myArray = New-Object string[] 10
因此,您在命令行上与之交互的是两个链接列表。我不确定 Powershell/.NET 如何处理复制链接列表,尽管从您的示例中可以看出,为了提高效率,它只$b
保留与相同的指针$a
,但是当您将一个项目添加到$b
或时$a
,它不会显示在另一个中,除非再次明确复制。我喜欢将其称为static copy
,但我不知道该术语在该领域是否有用。