Поделиться через


Неизменность

Все типы в 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# — это концепция, которая применяется к символу , а не к типу или значению; он применяется к дескриптору, который позволяет получить доступ к значению, а не к самому значению. Он не представлен в системе типов, неявно или явно.

Конечно, это просто описание формально определенного поведения; Под капотом фактическая реализация использует схему подсчета ссылок, чтобы избежать копирования памяти как можно больше. Изменение выполняется специально, если существует только один допустимый дескриптор, который обращается к определенному значению.