Precedência e associatividade
A precedência e a associatividade definem a ordem pela qual os operadores são aplicados. Os operadores com maior precedência estão vinculados aos seus argumentos (operandos) primeiro, enquanto os operadores com a mesma precedência vinculam-se na direção da sua associatividade.
Por exemplo, a expressão 1+2*3
de acordo com a precedência de adição e multiplicação é equivalente a e 2^3^4
é igual 2^(3^4)
a 1+(2*3)
uma vez que a exponenciação é associativa à direita.
Operadores
A tabela seguinte lista os operadores disponíveis no Q#, bem como a precedência e associatividade. Estão também listados modificadores e combinadores adicionais e vinculados mais apertados do que qualquer um destes operadores.
Description | Syntax | Operador | Associatividade | Precedência |
---|---|---|---|---|
operador copy-and-update | w/ <- |
ternary | esquerda | 1 |
operador range | .. |
infixo | esquerda | 2 |
operador condicional | ? \| |
ternary | right | 3 |
lógico OU | or |
infixo | esquerda | 4 |
lógico E | and |
infixo | esquerda | 5 |
bit-a-bit OU | \|\|\| |
infixo | esquerda | 6 |
bitwise XOR | ^^^ |
infixo | esquerda | 7 |
bitwise AND | &&& |
infixo | esquerda | 8 |
igualdade | == |
infixo | esquerda | 9 |
desigualdade | != |
infixo | esquerda | 9 |
menor que ou igual | <= |
infixo | esquerda | 10 |
menor do que | < |
infixo | esquerda | 11 |
maior do que ou igual | >= |
infixo | esquerda | 11 |
maior do que | > |
infixo | esquerda | 11 |
shift para a direita | >>> |
infixo | esquerda | 12 |
shift esquerdo | <<< |
infixo | esquerda | 12 |
adição ou concatenação | + |
infixo | esquerda | 13 |
subtração | - |
infixo | esquerda | 13 |
multiplicação | * |
infixo | esquerda | 14 |
divisão | / |
infixo | esquerda | 14 |
modulus | % |
infixo | esquerda | 14 |
exponenciação | ^ |
infixo | right | 15 |
bitwise NOT | ~~~ |
prefixo | right | 16 |
lógico NÃO | not |
prefixo | right | 16 |
negativo | - |
prefixo | right | 16 |
As expressões copy-and-update precisam necessariamente de ter a precedência mais baixa para garantir um comportamento consistente da instrução de avaliação e reatribuição correspondente. Considerações semelhantes para o operador de intervalo para garantir um comportamento consistente da expressão contextual correspondente.
Modificadores e combinadores
Os modificadores podem ser vistos como operadores especiais que só podem ser aplicados a determinadas expressões. Pode ser-lhes atribuída uma precedência artificial para capturar o seu comportamento.
Para obter mais informações, veja Expressões.
Esta precedência artificial está listada na tabela seguinte, juntamente com a forma como a precedência dos operadores e modificadores se relaciona com a forma como os combinadores de acesso aos itens ([
e::
,]
respetivamente) e os combinadores de chamadas ((
, )
) se vinculam.
Description | Syntax | Operador | Associatividade | Precedência |
---|---|---|---|---|
Combinador de chamadas | ( ) |
n/a | esquerda | 17 |
Functor adjacente | Adjoint |
prefixo | right | 18 |
Functor controlado | Controlled |
prefixo | right | 18 |
Desembrulhar a aplicação | ! |
postfixo | esquerda | 19 |
Acesso a itens nomeados | :: |
n/a | esquerda | 20 |
Acesso a item de matriz | [ ] |
n/a | esquerda | 20 |
Função lambda | -> |
n/a | right | 21 |
Operação lambda | => |
n/a | right | 21 |
Para ilustrar as implicações das precedências atribuídas, suponha que tem uma operação DoNothing
unitária (conforme definido em Declarações de especialização), um callable GetStatePrep
que devolve uma operação unitária e uma matriz algorithms
que contém itens do tipo Algorithm
definidos da seguinte forma
newtype Algorithm = (
Register : Qubit[],
Initialize : Transformation,
Apply : Transformation
);
newtype Transformation =
Qubit[] => Unit is Adj + Ctl;
As seguintes expressões são todas válidas:
GetStatePrep()(arg)
(Transformation(GetStatePrep()))!(arg)
Adjoint DoNothing()
Controlled Adjoint DoNothing(cs, ())
Controlled algorithms[0]::Apply!(cs, _)
algorithms[0]::Register![i]
Olhando para as precedências definidas na tabela acima, pode ver que os parênteses à volta (Transformation(GetStatePrep()))
são necessários para que o operador de desembrulhar subsequente seja aplicado ao Transformation
valor em vez da operação devolvida.
No entanto, os parênteses não são necessários em GetStatePrep()(arg)
; as funções são aplicadas da esquerda para a direita, pelo que esta expressão é equivalente a (GetStatePrep())(arg)
.
As aplicações de functor também não necessitam de parênteses à sua volta para invocar a especialização correspondente, nem expressões de acesso de matriz ou item nomeado. Assim, a expressão arr2D[i][j]
é perfeitamente válida, tal como .algorithms[0]::Register![i]
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários