Confirmação do comportamento do PowerShell em matrizes

1

Considere o seguinte script pequeno:

$a = @(1,2,3)         #1
$b = $a               #2
$a[0] = 101           #3
$b += 99              #4
Write-Host "a: $a"
Write-Host "b: $b"

A saída é essa que me obrigou a pensar um pouco:

a: 101 2 3 b: 101 2 3 99

Minhas observações para esclarecimento:

  1. A matriz $ b contém quatro elementos na saída, então $ b = $ a está criando uma cópia da matriz original com três itens e, em seguida, o elemento 99 é adicionado. Se $ b = $ a fosse uma operação de ponteiro, então adicionar um elemento a $ b também afetaria a matriz $ a
  2. A matriz contém ponteiros para os inteiros e não os inteiros. Provado pelo fato de que a linha 3 altera o conteúdo de ambas as matrizes. Se $ a continha números inteiros, então $ b não teria sido afetado

Então, meu entendimento é:

Uma matriz do PowerShell é sempre uma matriz de ponteiros, mesmo que contenha apenas inteiros. Atribuir um array a outra variável cria uma cópia desse array de ponteiros.

certo?

    
por Rob Nicholson 07.02.2014 / 14:06

2 respostas

3

Não sei a verdadeira razão por trás disso, mas se você observar esse comportamento, poderá começar a entender:

$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

Você pode ver que ele não "vincula" $b a $a e, em vez disso, o inicializa como uma matriz separada.

Outras leituras em Tipos de valor VS Tipos de referência

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

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

    
por 09.02.2014 / 02:48
1

Acho que internamente eles são implementados como listas vinculadas e não como arrays. A diferença é que é muito caro adicionar um item a uma matriz, porque o tamanho de uma matriz é declarado, então a memória contígua é alocada para ela. Por causa disso, não há garantia de que o próximo bloco contíguo de memória esteja disponível para o array, e um novo array de tamanho (origArray + 1) deve ser criado, o array antigo copiado e o novo elemento copiado também . Eu não tenho nenhuma prova disso, claro, além da experiência de programação e observando o comportamento do PowerShell.

Atualizar

Eu tenho provas! Evitando o operador de lista vs Como uma matriz é declarada no powershell. Observe o usuário do cmdlet New-Object ao declarar uma matriz:

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

Então, o que você está interagindo na linha de comando são duas listas vinculadas. Não tenho certeza de como o Powershell / .NET manipula a cópia de listas vinculadas, embora pareça a partir do seu exemplo que $b simplesmente mantém os mesmos ponteiros que $a , mas quando você adiciona um item a $b ou $a não aparece no outro, a menos que explicitamente copiado novamente. Eu gosto de me referir a isso como um static copy , embora eu não saiba se esse termo tem uso no campo.

    
por 07.02.2014 / 15:07

Tags