* 运算符事实上对 LHS 数组所做的就是将该数组的元素按原样用作结果数组的元素。
在本例中,这意味着$matrix[0]、$matrix[1]和$matrix[2]都指向由@组成的相同5元素数组 987654325@ 字符串,因此修改一个数组的元素将反映在所有 3 个$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() }
顺便说一句:上面创建了一个锯齿状数组,而不是一个矩阵(二维数组)。以下是创建真正的二维数组的方法:
$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] 而不是 [0][1]。
设计思考:
我只能推测设计意图,但我认为 没有 尝试克隆恰好是 LHS 数组元素的集合,因为有不保证此类集合可以被克隆 - 这同样适用于 LHS 数组的所有元素类型引用类型(字符串除外)。
使用 值类型 或 字符串 的 LHS 数组元素 - 这是更典型的情况 - 没有问题,因为生成的数组元素将(有效地)独立副本。
简而言之:对于 * 的可预测数组复制,将 LHS 数组的元素类型限制为 值类型 或 字符串。