Неизменность
Все типы в Q#типы значений.
Q# не имеет понятия ссылки или указателя. Вместо этого он позволяет переназначить новое значение ранее объявленной переменной с помощью выражения назначения. Например, нет различия в поведении между переназначениями для переменных типа Int
или переменных типа Int[]
. Рассмотрим следующую последовательность операторов:
mutable arr1 = new Int[3];
let arr2 = arr1;
arr1 w/= 0 <- 3;
Первая инструкция создает экземпляр нового массива целых чисел [0,0,0]
и назначает его arr1
.
Следующая инструкция назначает это значение переменной с именем arr2
. Последняя инструкция создает новый экземпляр массива на основе arr1
с теми же значениями, за исключением значения в индексе 0, который имеет значение 3. Затем созданный массив назначается переменной arr1
. Последняя строка использует сокращенный синтаксис для операторов оценки и переназначения, и может быть эквивалентно написан как arr1 = arr1 w/ 0 <- 1;
.
После выполнения трех инструкций arr1
будет содержать значение [3,0,0]
, пока arr2
остается неизменным и содержит значение [0,0,0]
.
Q# четко различает мутируемость дескриптора и поведения типа. Мутируемость в Q# — это концепция, которая применяется к символу , а не к типу или значению; он применяется к дескриптору, который позволяет получить доступ к значению, а не к самому значению. Он не представлен в системе типов, неявно или явно.
Конечно, это просто описание формально определенного поведения; Под капотом фактическая реализация использует схему подсчета ссылок, чтобы избежать копирования памяти как можно больше. Изменение выполняется специально, если существует только один допустимый дескриптор, который обращается к определенному значению.