我无法理解Powershell中的这种行为:
$PSVersionTable.PSVersion
""
$matrix =, @(, @("foo") * 5) * 3
$matrix[0][1] = "bar"
foreach($subArray in $matrix){
Write-Host $($subArray[1])
}
使用此脚本,我将初始化一个由3个数组组成的数组,每个数组包含5个字符串“ foo”。
我想将第一个数组的第二个元素设置为“ bar”,并且每个数组都会受到影响:
# Returned :
Major Minor Build Revision
----- ----- ----- --------
5 1 15063 1155
bar
bar
bar
是错误还是我误解了数组的工作原理?
答案 0 :(得分:3)
switch
运算符实际上是作为LHS对数组进行的操作,是将该数组的元素原样用作结果数组的元素。
在当前情况下,这意味着 *
,$matrix[0]
和$matrix[1]
都指向相同 5元素数组< / strong>由$matrix[2]
个字符串组成,因此修改一个数组的元素将反映在所有3个"foo"
元素中。
这种行为很可能是设计使然(请参阅底部),并且我不知道使用$matrix
语法的简洁解决方法。
可行的解决方法是:
*
顺便说一句:上面创建了一个锯齿状的数组 ,而不是矩阵(二维数组)。这是创建真正的二维数组的方法:
# Note: The (...) around the arrays to replicate aren't strictly needed,
# because `,` has higher precedence than `*`, but were added for
# readability.
$nestedArrayTemplate = (, 'foo') * 5
$matrix = (, @()) * 3 # (, $null) * 3 would work too
for ($i=0; $i -lt $matrix.Count; ++$i) { $matrix[$i] = $nestedArrayTemplate.Clone() }
请注意,索引到此二维数组中需要一个单个索引表达式和一个 list 索引;例如$matrix = [string[,]]::new(3, 5) # PSv4-: New-Object string[] 3, 5
for ($row = 0; $row -lt $matrix.GetLength(0); ++$row) {
for ($col = 0; $col -lt $matrix.GetLength(1); ++$col ){
$matrix[$row, $col] = 'foo'
}
}
,而不是[0, 1]
。
设计灵感:
我只能推测一下设计意图,但我想尝试 no 尝试对恰好是LHS数组元素的 clone 集合进行尝试,因为不能保证可以克隆这样的集合 -更普遍的是,LHS数组的所有类型都是引用类型(字符串除外)的元素类型。
使用Lem数组元素为值类型或 strings -这是最典型的情况-没问题,因为结果数组的元素将(有效)独立副本。
简而言之:要使用[0][1]
进行可预测的数组复制,请将LHS数组的元素类型限制为值类型或字符串。