Expressões de cópia e atualização
Para reduzir a necessidade de associações mutáveis, Q# dá suporte a expressões de cópia e atualização para matrizes, que permitem acessar itens por meio de um índice ou intervalo de índices.
Expressões de cópia e atualização instanciam uma nova matriz com todos os itens definidos como o valor correspondente na matriz original, exceto os determinados itens especificados, que são definidos como aqueles definidos no lado direito da expressão.
Eles são construídos usando um operador ternário w/
<-
; a sintaxe w/
deve ser lida como a notação curta comumente usada para "with":
original w/ itemAccess <- modification
em que original
é uma expressão de matriz, itemAccess
é qualquer expressão válida para o fatiamento de matriz e modification
é o novo valor ou valores. Concretamente, a expressão itemAccess
pode ser do tipo Int
ou Range
. Se itemAccess
for um valor do tipo Int
, o tipo de modification
deverá corresponder ao tipo de item da matriz. Se itemAccess
for um valor do tipo Range
, o tipo de modification
deverá ser o mesmo que o tipo de matriz.
Por exemplo, se arr
contiver uma matriz [0, 1, 2, 3]
, então
-
arr w/ 0 <- 10
é a matriz[10, 1, 2, 3]
. -
arr w/ 2 <- 10
é a matriz[0, 1, 10, 3]
. -
arr w/ 0..2..3 <- [10, 12]
é a matriz[10, 1, 12, 3]
.
Em termos de precedência, o operador copy-and-update é associativo à esquerda e tem precedência mais baixa e, em particular, precedência menor que o operador de intervalo (..
) ou o operador condicional ternário (?
|
).
A associatividade esquerda escolhida permite o encadeamento fácil de expressões de cópia e atualização:
let model = ArrayConstructor()
w/ 1 <- alpha
w/ 3 <- gamma
w/ 5 <- epsilon;
Quanto a qualquer operador que construa uma expressão do mesmo tipo que a expressão mais à esquerda envolvida, o instrução evaluate-and-reassign correspondente está disponível.
As duas instruções a seguir, por exemplo, alcançam o seguinte: a primeira instrução declara uma variável mutável arr
e associá-la ao valor padrão de uma matriz de inteiros. Em seguida, a segunda instrução cria uma nova matriz com o primeiro item (com índice 0) definido como 10 e reatribui-a para arr
.
mutable arr = [0, size = 3]; // arr contains [0, 0, 0]
arr w/= 0 <- 10; // arr contains [10, 0, 0]
A segunda instrução é apenas abreviada para a sintaxe mais detalhada arr = arr w/ 0 <- 10;
.
As expressões de cópia e atualização permitem a criação eficiente de novas matrizes com base nas existentes. A implementação de expressões de cópia e atualização evita copiar toda a matriz duplicando apenas as partes necessárias para alcançar o comportamento desejado e executa uma modificação in-loco, se possível. Portanto, as inicializações de matriz não incorrem em sobrecarga adicional devido à imutabilidade.
O namespace Std.Arrays
fornece um arsenal de ferramentas convenientes para criação e manipulação de matriz.
Expressões de cópia e atualização são uma maneira conveniente de construir novas matrizes em tempo real; a expressão a seguir, por exemplo, é avaliada como uma matriz com todos os itens definidos como PauliI
, exceto o item no índice i
, que é definido como PauliZ
:
[PauliI, size = n] w/ i <- PauliZ