不変性

Q# でのすべての型は "値の型" です。 Q# には、参照またはポインターの概念がありません。 代わりに、set ステートメントを使用して、前に宣言された変数に新しい値を再割り当てすることができます。 たとえば、再割り当て (たとえば、型 Int の変数または型 Int[] の変数) の間に動作の区別はありません。 次のような一連のステートメントについて考えてみます。

    mutable arr1 = new Int[3];
    let arr2 = arr1; 
    set arr1 w/= 0 <- 3; 

最初のステートメントでは、整数 [0,0,0] の新しい配列をインスタンス化し、それを arr1 に割り当てます。 次のステートメントでは、その値を arr2 という名前の変数に割り当てます。 最後のステートメントでは、3 に設定されているインデックス 0 の値を除き同じ値を使用して、arr1 に基づく新しい配列インスタンスを作成します。 新しく作成された配列は、その後、変数 arr1 に割り当てられます。 最後の行は、evaluate-and-reassign ステートメントの省略された構文を使用しており、同等に set arr1 = arr1 w/ 0 <- 1; と記述することもできます。
これらの 3 つのステートメントを実行すると、arr1 には値 [3,0,0] が含まれるのに対して、arr2 は変更されないままで [0,0,0] が含まれます。

Q# では、このように、ハンドルの変更可能性と型の動作を明確に区別します。 Q# 内の変更可能性は、型または値ではなく、"シンボル" に適用される概念です。これは、値自体にではなく、その値へのアクセスを可能にするハンドルに適用されます。 これは、暗黙的にも明示的にも、型システムでは表され "ません"。

もちろん、これは、正式に定義されている動作の説明にすぎません。内部では、メモリのコピーをできるだけ回避するために、実際の実装によって参照カウント スキームが使用されます。 特に、特定の値にアクセスする現在有効なハンドルが 1 つだけである限り、変更はインプレースで実行されます。