Precedência e capacidade de associação
Precedência e associatividade definem a ordem na qual os operadores são aplicados. Operadores com precedência mais alta são associados a seus argumentos (operandos) primeiro, enquanto os operadores com a mesma precedência se associam na direção de sua associatividade.
Por exemplo, a expressão 1+2*3
de acordo com a precedência de adição e multiplicação é equivalente a 1+(2*3)
e 2^3^4
é igual a 2^(3^4)
uma vez que a exponencialização é associativa à direita.
Operadores
A tabela a seguir lista os operadores disponíveis em Q#, bem como sua precedência e associatividade. Modificadores e combinadores de adicionais também são listados e associam mais apertados do que qualquer um desses operadores.
Descrição | Sintaxe | Operador | Capacidade de associação | Precedência |
---|---|---|---|---|
operador de cópia e atualização |
w/
<-
|
Ternário | Esquerda | 1 |
operador de intervalo | .. |
infix | Esquerda | 2 |
operador condicional | ? \| |
Ternário | Certo | 3 |
or lógica | or |
infix | Esquerda | 4 |
lógico AND | and |
infix | Esquerda | 5 |
or bit a bit | \|\|\| |
infix | Esquerda | 6 |
XOR bit a bit | ^^^ |
infix | Esquerda | 7 |
AND bit a bit | &&& |
infix | Esquerda | 8 |
de igualdade | == |
infix | Esquerda | 9 |
de desigualdade | != |
infix | Esquerda | 9 |
menor ou igual a | <= |
infix | Esquerda | 10 |
menos de | < |
infix | Esquerda | 11 |
maior que ou igual a | >= |
infix | Esquerda | 11 |
maior que | > |
infix | Esquerda | 11 |
de turno para a direita | >>> |
infix | Esquerda | 12 |
de turno esquerdo | <<< |
infix | Esquerda | 12 |
adição ou de concatenação | + |
infix | Esquerda | 13 |
de subtração | - |
infix | Esquerda | 13 |
de multiplicação | * |
infix | Esquerda | 14 |
divisão | / |
infix | Esquerda | 14 |
módulo | % |
infix | Esquerda | 14 |
de exponencialização | ^ |
infix | Certo | 15 |
NOT bit a bit | ~~~ |
prefixo | Certo | 16 |
lógico NÃO | not |
prefixo | Certo | 16 |
negativo | - |
prefixo | Certo | 16 |
As expressões de cópia e atualização necessariamente precisam ter a menor precedência para garantir um comportamento consistente da instrução de avaliação e reatribução correspondente. Considerações semelhantes são consideradas para o operador de intervalo para garantir um comportamento consistente do expressão contextual correspondente.
Modificadores e combinadores
Os modificadores podem ser vistos como operadores especiais que podem ser aplicados somente a determinadas expressões. Eles podem receber uma precedência artificial para capturar seu comportamento.
Para obter mais informações, consulte Expressions.
Essa precedência artificial é listada na tabela a seguir, juntamente com a forma como a precedência de operadores e modificadores se relaciona com a associação de combinadores de acesso de itens ([
,]
e ::
respectivamente) e combinadores de chamadas ((
, )
).
Descrição | Sintaxe | Operador | Capacidade de associação | Precedência |
---|---|---|---|---|
do combinador de chamadas |
(
)
|
n/a | Esquerda | 17 |
functor adjacente | Adjoint |
prefixo | Certo | 18 |
de functor controlado | Controlled |
prefixo | Certo | 18 |
desembrulhar de aplicativo | ! |
Postfix | Esquerda | 19 |
acesso ao item nomeado | . |
n/a | Esquerda | 20 |
de acesso de item do Array |
[
]
|
n/a | Esquerda | 20 |
função lambda | -> |
n/a | Certo | 21 |
Operação lambda | => |
n/a | Certo | 21 |
Para ilustrar as implicações das precedências atribuídas, suponha que você tenha uma operação unitária DoNothing
(conforme definido em declarações de especialização ), um GetStatePrep
que retorna uma operação unitária e uma matriz algorithms
que contém itens do tipo Algorithm
definidos da seguinte maneira
struct Algorithm {
Register : Qubit[],
Initialize : Transformation,
Apply : Transformation,
}
As seguintes expressões, então, são todas válidas:
GetStatePrep()(arg)
Adjoint DoNothing()
Controlled Adjoint DoNothing(cs, ())
Controlled algorithms[0].Apply!(cs, _)
algorithms[0].Register![i]
Examinando as precedências definidas na tabela acima, você pode ver que os parênteses em torno de (Transformation(GetStatePrep()))
são necessários para que o operador de unwrap subsequente seja aplicado ao valor Transformation
em vez da operação retornada.
No entanto, parênteses não são necessários no GetStatePrep()(arg)
; as funções são aplicadas da esquerda para a direita, portanto, essa expressão é equivalente a (GetStatePrep())(arg)
.
Os aplicativos functor também não exigem parênteses ao seu redor para invocar a especialização correspondente, nem expressões de acesso de itens nomeados ou matriz. Portanto, a expressão arr2D[i][j]
é perfeitamente válida, assim como algorithms[0]::Register![i]
.