你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
优先级和结合性
优先级和结合性定义了运算符的应用顺序。 具有较高优先级的运算符会首先绑定到其参数(操作数),而具有相同优先级的运算符取决于其相关性方向。
例如,根据加法和乘法的优先级,表达式 1+2*3
等价于 1+(2*3)
,且 2^3^4
等价于 2^(3^4)
,因为乘方是右结合的。
运算符
下表列出了 Q# 中可用的运算符,以及它们的优先级和结合性。 其他修饰符和连结符也被列出,并且比这些运算符中任何一个的绑定都更紧密。
说明 | 语法 | 操作员 | 结合性 | 优先级 |
---|---|---|---|---|
复制和更新运算符 | w/ <- |
三重的 | left | 1 |
range 运算符 | .. |
中辍 | left | 2 |
条件运算符 | ? \| |
三重的 | right | 3 |
逻辑或 | or |
中辍 | left | 4 |
逻辑与 | and |
中辍 | left | 5 |
位或 | \|\|\| |
中辍 | left | 6 |
位异或 | ^^^ |
中辍 | left | 7 |
位与 | &&& |
中辍 | left | 8 |
等于 | == |
中辍 | left | 9 |
不等于 | != |
中辍 | left | 9 |
小于或等于 | <= |
中辍 | left | 10 |
小于 | < |
中辍 | left | 11 |
大于或等于 | >= |
中辍 | left | 11 |
大于 | > |
中辍 | left | 11 |
右移 | >>> |
中辍 | left | 12 |
左移 | <<< |
中辍 | left | 12 |
加或串联 | + |
中辍 | left | 13 |
减 | - |
中辍 | left | 13 |
乘 | * |
中辍 | left | 14 |
除 | / |
中辍 | left | 14 |
取模 | % |
中辍 | left | 14 |
乘方 | ^ |
中辍 | right | 15 |
位非 | ~~~ |
prefix | right | 16 |
逻辑非 | not |
prefix | right | 16 |
negative | - |
prefix | right | 16 |
复制和更新表达式必须具有最低优先级,以确保相应计算和重新分配语句的行为一致。 对于范围运算符也有类似的考虑,以确保相应上下文表达式的行为一致。
修饰符和连结符
修饰符可以看作是只能应用于某些表达式的特殊运算符。 可以为它们分配一个自定义优先级来捕捉其行为。
有关详细信息,请参阅表达式。
这种自定义优先级在下表中列出,表中还显示了运算符和修饰符的优先级与项访问连结符(分别为 [
、]
和 ::
)和调用连结符((
、)
)绑定紧密程度的联系。
说明 | 语法 | 操作员 | 结合性 | 优先级 |
---|---|---|---|---|
调用连结符 | ( ) |
不适用 | left | 17 |
伴随函子 | Adjoint |
prefix | right | 18 |
受控函子 | Controlled |
prefix | right | 18 |
展开应用程序 | ! |
postfix | left | 19 |
命名项访问 | :: |
不适用 | left | 20 |
数组项访问 | [ ] |
不适用 | left | 20 |
函数 lambda | -> |
不适用 | right | 21 |
操作 lambda | => |
不适用 | right | 21 |
为了说明分配的优先级的含义,假设你有一个(在特殊化声明中定义的)幺正运算 DoNothing
、一个返回幺正运算的可调用对象 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]
查看上表中定义的优先级,可以看到后续 unwrap 运算符应用于 Transformation
值而不是返回的运算,因此 (Transformation(GetStatePrep()))
两边的括号是必要的。
但是,GetStatePrep()(arg)
中不需要括号;函数从左到右应用,所以这个表达式等价于 (GetStatePrep())(arg)
。
函子应用无需加括号来调用相应的特殊化,数组或命名项访问表达式也不需要。 因此,表达式 arr2D[i][j]
是完全有效的,algorithms[0]::Register![i]
也是。