Imutabilidade
Todos os tipos em Q# são tipos de valor.
Q# não tem um conceito de referência ou ponteiro. Em vez disso, permite que você reatribua um novo valor a uma variável declarada anteriormente por meio de uma expressão de atribuição. Por exemplo, não há distinção no comportamento entre reatribuções para variáveis do tipo Int
ou variáveis do tipo Int[]
. Considere a seguinte sequência de instruções:
mutable arr1 = new Int[3];
let arr2 = arr1;
arr1 w/= 0 <- 3;
A primeira instrução cria uma instância de uma nova matriz de inteiros [0,0,0]
e a atribui a arr1
.
A próxima instrução atribui esse valor a uma variável com o nome arr2
. A última instrução cria uma nova instância de matriz com base em arr1
com os mesmos valores, exceto pelo valor no índice 0, que é definido como 3. A matriz recém-criada é atribuída à variável arr1
. A última linha usa a sintaxe abreviada para instruções de avaliação e reatribuçãoe poderia ter sido escrita como arr1 = arr1 w/ 0 <- 1;
.
Depois de executar as três instruções, arr1
conterá o valor [3,0,0]
enquanto arr2
permanecer inalterado e contiver o valor [0,0,0]
.
Q# distingue claramente a mutabilidade de um identificador e o comportamento de um tipo. A mutabilidade dentro de Q# é um conceito que se aplica a um símbolo em vez de um tipo ou valor; aplica-se ao identificador que permite acessar um valor em vez do próprio valor. Não é representado no sistema de tipos, implicitamente ou explicitamente.
É claro que isso é apenas uma descrição do comportamento formalmente definido; sob o capô, a implementação real usa um esquema de contagem de referência para evitar copiar memória o máximo possível. A modificação é feita especificamente em vigor, desde que haja apenas um identificador válido no momento que acesse um determinado valor.