優先順位と結合規則
優先順位と結合性により、演算子が適用される順序が定義されます。 優先順位が高い演算子は最初に引数 (オペランド) にバインドされ、同じ優先順位の演算子は結合性の方向にバインドされます。
たとえば、式 1+2*3
は、加算と乗算の優先順位に従い、1+(2*3)
と等しく、累乗は右結合型であるため、2^3^4
は 2^(3^4)
と等しくなります。
演算子
次の表に、Q# で使用できる演算子とその優先順位と結合性を示します。 また、別途掲載した追加の修飾子と連結子は、これらの演算子よりも緊密にバインドされます。
説明 | 構文 | Operator | 結合規則 | 優先順位 |
---|---|---|---|---|
コピーと更新の演算子 | w/ <- |
三 項 | 左 | 1 |
range 演算子 | .. |
挿入辞 | 左 | 2 |
条件付きの演算子 | ? \| |
三 項 | right | 3 |
論理 OR | or |
挿入辞 | 左 | 4 |
論理 AND | and |
挿入辞 | 左 | 5 |
ビット単位の OR | \|\|\| |
挿入辞 | 左 | 6 |
ビット単位の XOR | ^^^ |
挿入辞 | 左 | 7 |
ビット単位の AND | &&& |
挿入辞 | 左 | 8 |
等式 | == |
挿入辞 | 左 | 9 |
不等式 | != |
挿入辞 | 左 | 9 |
以下 | <= |
挿入辞 | 左 | 10 |
より小さい | < |
挿入辞 | 左 | 11 |
以上 | >= |
挿入辞 | 左 | 11 |
より大きい | > |
挿入辞 | 左 | 11 |
右シフト | >>> |
挿入辞 | 左 | 12 |
左シフト | <<< |
挿入辞 | 左 | 12 |
加算または連結 | + |
挿入辞 | 左 | 13 |
減算 | - |
挿入辞 | 左 | 13 |
乗算 | * |
挿入辞 | 左 | 14 |
除算 | / |
挿入辞 | 左 | 14 |
modulus | % |
挿入辞 | 左 | 14 |
累乗 | ^ |
挿入辞 | right | 15 |
ビット単位の NOT | ~~~ |
prefix | right | 16 |
論理 NOT | not |
prefix | right | 16 |
negative | - |
prefix | right | 16 |
コピーと更新の式は、対応する evaluate-and-reassign ステートメントとの一貫した動作を確保するために、最も低い優先順位が必要です。 範囲演算子にも同様の考慮事項があり、対応するコンテキスト式との一貫した動作を確保する必要があります。
修飾子と連結子
修飾子は、特定の式にのみ適用できる特殊な演算子と考えることができます。 これらには、その動作を捕捉するために、人為的な優先順位を割り当てることができます。
詳細については、「式」をご覧ください。
この人為的な優先順位を次の表に示します。演算子と修飾子の優先順位が、項目アクセス結合子 (それぞれ [
、]
、::
) と呼び出し結合子 ((
、)
) のバインドの緊密さとどう関係しているかも示しています。
説明 | 構文 | Operator | 結合規則 | 優先順位 |
---|---|---|---|---|
呼び出し結合子 | ( ) |
該当なし | 左 | 17 |
Adjoint 関手 | Adjoint |
prefix | right | 18 |
Controlled 関手 | Controlled |
prefix | right | 18 |
アンラップ適用 | ! |
postfix | 左 | 19 |
名前付き項目へのアクセス | :: |
該当なし | 左 | 20 |
配列項目へのアクセス | [ ] |
該当なし | 左 | 20 |
関数ラムダ | -> |
該当なし | right | 21 |
演算ラムダ | => |
該当なし | right | 21 |
割り当てられた優先順位の影響を示すために、「特殊化宣言」で定義されている単一演算 DoNothing
、単一演算を返す callable GetStatePrep
、次のように定義された Algorithm
型の項目を含む配列 algorithms
があるとします
newtype Algorithm = (
Register : Qubit[],
Initialize : Transformation,
Apply : Transformation
);
newtype Transformation =
Qubit[] => Unit is Adj + Ctl;
次の式はすべて有効です。
GetStatePrep()(arg)
(Transformation(GetStatePrep()))!(arg)
Adjoint DoNothing()
Controlled Adjoint DoNothing(cs, ())
Controlled algorithms[0]::Apply!(cs, _)
algorithms[0]::Register![i]
上の表で定義されている優先順位によれば、後続のアンラップ演算子を、返される演算ではなく Transformation
の値に適用するには、(Transformation(GetStatePrep()))
の周りのかっこが必要であることが分かります。
ただし、GetStatePrep()(arg)
にはかっこは必要ありません。関数は左から右に適用されるため、この式は (GetStatePrep())(arg)
と同じです。
また、関手の適用でも、対応する特殊化を呼び出すために、それらをかっこで囲む必要はありません。配列および名前付き項目へのアクセス式も同様です。 algorithms[0]::Register![i]
と同様に、arr2D[i][j]
も完全に有効な式です。